在CUDA中重叠数据传输和内核执行时,我观察到一种奇怪的行为。
在cudaMemcpyAsync
之后调用cudaMemsetAsync
虽然cudaMemsetAsync
确实与计算内核重叠,但cudaMemcpyAsync
没有。{1}}。
计算内核结束,然后执行cudaMemcpyAsync
。
在评论cudaMemsetAsync
时,重叠将正确执行。
部分代码如下所示,并进行了一些更改。
代码:
for (d = 0; d < TOTAL; ++d){
gpuErrchk(cudaMemsetAsync(data_d, 0, bytes, stream1));
for (j = 0; j < M; ++j)
{
gpuErrchk(cudaMemcpyAsync(&data_d[index1], &data_h[index2], bytes, H2D, stream1));
}
gpuErrchk(cudaStreamSynchronize(stream1));
cufftExecR2C(plan, data_d, data_fft_d);
gpuErrchk(cudaStreamSynchronize(stream2));
kernel<<dimGrid, dimBlock,0, stream3>>(result_d, data_fft_d, size);
}
我使用NVIDIA GTX-Titan GPU,计算和内存操作在不同的流中执行。此外,cudaMemsetAsync
和cudaMemcpyAsync
在同一设备缓冲区上运行。
答案 0 :(得分:2)
一些CUDA的memcpy函数是用内核实现的(例如device-&gt; device memcpy),但所有CUDA的memset函数都在内部实现为内核。
假设cufftExecR2C
调用应该在不同的流中完成,你可以打赌,FFT计划生成的内核被设计为完全占用GPU。
因此,如果您尝试在另一个流中调用内核,则可能会遇到与内核并发相同的限制。内核必须占用有限数量的GPU才能同时运行,但大多数CUDA内核并不是为了适应这种用例而设计的。