如果我有两个cudaMalloc
ed数组,我可以通过交换相关指针来交换它们而无需记忆移动。交换CUDA无记忆移动的推力设备向量
如果我有两个CUDA推力device_vectors,说d_a
和d_b
,我可以通过使用第三temorary向量交换他们,说d_c
,但这将需要记忆的动作。
我的问题是:有没有办法将CUDA Thrust device_vectors交换为无内存移动?
如果我有两个cudaMalloc
ed数组,我可以通过交换相关指针来交换它们而无需记忆移动。交换CUDA无记忆移动的推力设备向量
如果我有两个CUDA推力device_vectors,说d_a
和d_b
,我可以通过使用第三temorary向量交换他们,说d_c
,但这将需要记忆的动作。
我的问题是:有没有办法将CUDA Thrust device_vectors交换为无内存移动?
不是我所知道的。
没有公开的构造函数需要现有的device_ptr
,并且device_vector
中的底层基向量是私有的,所以无法潜入并自己执行指针交换。这些将是我能想到的唯一方法,使其在不触发标准拷贝构造函数的情况下进行这项工作。
编辑补充说它看起来这个答案是错误的。看来最近(可能在推力1.6左右)的变化已经实现了一个内部指针交换交换机制,可以通过device_vector.swap()
调用。这绕开了通常的swap()
的复制构造函数成语,并且不会触发内存传输 。
如果您不知道,那么99.99%可能是不可能的:-)谢谢,一如既往。 – JackOLantern
想一想,你可以通过黑客自定义的分配器类来执行操作,该类会返回另一个设备向量的内存。但是,你有很多其他问题可能无法解决 – talonmies
只是一个问题:'d_b.swap(d_a)'暗示内存移动? – JackOLantern
看起来device_vector.swap()
可以避免内存移动。使用
d_b.swap(d_a);
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>
#include <thrust\device_vector.h>
void printDeviceVector(thrust::device_vector<int> &d_a) {
for (int k = 0; k < d_a.size(); k++) {
int temp = d_a[k];
printf("%i\n", temp);
}
}
int main()
{
const int N = 10;
thrust::device_vector<int> d_a(N, 1);
thrust::device_vector<int> d_b(N, 2);
// --- Original
printf("Original device vector d_a\n");
printDeviceVector(d_a);
printf("Original device vector d_b\n");
printDeviceVector(d_b);
d_b.swap(d_a);
// --- Original
printf("Final device vector d_a\n");
printDeviceVector(d_a);
printf("Final device vector d_b\n");
printDeviceVector(d_b);
d_a.clear();
thrust::device_vector<int>().swap(d_a);
d_b.clear();
thrust::device_vector<int>().swap(d_b);
cudaDeviceReset();
return 0;
}
如果我们描述文件时,我们看到在时间轴上没有设备到设备内存运动:
事实上,考虑下面的代码
如果在另一方面我们更改d_b.swap(d_a)
到
d_b = d_a;
然后设备到设备的运动出现在时间轴:
最后,定时是显著赞成d_b.swap(d_a)
,而不是d_b = d_a
。对于N = 33554432
,定时是
d_b.swap(d_a) 0.001152ms
d_b = d_a 3.181824ms
的'推力:: VECTOR'类具有用于存储所述矢量内容类型'contiguous_storage'的成员。当矢量交换时,内部只交换'contiguous_storage'的'begin()'迭代器,'size'和'allocator'。所以没有涉及数据的内存拷贝。你可以在文件'contiguous_storage.inl'内的['swap'](https://github.com/thrust/thrust/blob/master/ thr/modules/contact.inl#L181)成员函数中检查它。 – sgarizvi
在赋值运算符的情况下,如果查看['vector_base :: operator =']的代码(https://github.com/thrust/thrust/blob/master/thrust/detail/vector_base.inl#L89 ),它使用似乎执行矢量内容的完整存储器复制的'assign'函数。 – sgarizvi
@sgarizvi感谢您的意见。其实,这是@talonmies在他的评论中指出的同样的反对意见。然而,奇怪的是我无法在时间轴中找到内存拷贝。也许'thrust'使用内核来执行复制? – JackOLantern