我想使用推力将内存从主机复制到设备
thrust::host_vector<float> h_vec(1 << 28);
thrust::device_vector<float> d_vec(1 << 28);
thrust::copy(h_vec.begin(), h_vec.end(), d_vec.begin());
使用CUDA流类似于使用流将内存从设备复制到设备的方式:
cudaStream_t s;
cudaStreamCreate(&s);
thrust::device_vector<float> d_vec1(1 << 28), d_vec2(1 << 28);
thrust::copy(thrust::cuda::par.on(s), d_vec1.begin(), d_vec1.end(), d_vec2.begin());
cudaStreamSynchronize(s);
cudaStreamDestroy(s);
问题是我无法将执行策略设置为CUDA以在从主机复制到设备时指定流,因为在这种情况下,推力会假设两个向量都存储在设备上 . 有办法解决这个问题吗?我正在使用github的最新推力版本(它在version.h文件中显示为1.8) .
2 回答
如评论中所示,我认为这不可能直接用
thrust::copy
. 但是,我们可以在推力应用程序中使用cudaMemcpyAsync
来实现异步复制和复制与计算重叠的目标 .这是一个有效的例子:
对于我的测试用例,我使用了RHEL5.5,Quadro5000和cuda 6.5RC . 这个例子被设计为推力创建非常小的内核(只有一个线程块,只要
KSIZE
很小,比如32或64),这样从thrust::for_each
创建的内核能够同时运行 .当我分析这段代码时,我看到:
这表明我们正在实现推力内核之间以及复制操作和推力内核之间的正确重叠,以及在内核完成时异步数据复制 . 请注意
cudaDeviceSynchronize()
操作"fills"时间轴,表示所有异步操作(数据复制,推力函数)都是异步发出的,并且控制在任何操作进行之前都返回到主机线程 . 所有这些都是预期的,主机,GPU和数据复制操作之间完全并发的正确行为 .这是一个使用
thrust::cuda::experimental::pinned_allocator<T>
的工作示例:注释掉同步步骤,由于异步内存传输,您应该将
0
打印到控制台 .