Concurrency cudaMemsetAsync异常行为

Concurrency cudaMemsetAsync异常行为,concurrency,cuda,overlap,Concurrency,Cuda,Overlap,在CUDA中,当重叠数据传输和内核执行时,我观察到一种奇怪的行为 在cudamemssetasync之后调用cudamemssetasync时,虽然cudamemssetasync与计算内核重叠,但cudaMemcpyAsync不重叠。 计算内核结束,然后执行cudaMemcpyAsync。 注释掉cudaMemsetAsync时,正确执行重叠 下面给出了部分代码,并进行了一些更改 代码: (d=0;d

在CUDA中,当重叠数据传输和内核执行时,我观察到一种奇怪的行为

cudamemssetasync
之后调用
cudamemssetasync
时,虽然
cudamemssetasync
与计算内核重叠,但
cudaMemcpyAsync
不重叠。 计算内核结束,然后执行
cudaMemcpyAsync
。 注释掉
cudaMemsetAsync
时,正确执行重叠

下面给出了部分代码,并进行了一些更改

代码:

(d=0;d
我使用NVIDIA GTX Titan GPU,计算和内存操作在不同的流中执行。此外,
cudaMemsetAsync
cudaMemcpyAsync
在同一个设备缓冲区上运行。

CUDA的一些memcpy函数是用内核实现的(如device->device memcpy),但CUDA的所有memset函数都是作为内核在内部实现的

假设
cufftExecR2C
调用应该在不同的流中完成,您可以打赌,FFT计划生成的内核被设计为完全占用GPU


因此,在内核并发性方面,您可能遇到了与在另一个流中调用内核时相同的限制。内核必须占用有限数量的GPU才能并行运行,但大多数CUDA内核的设计并不能适应该用例。

您能在这里展示您的代码吗?如果是,请尽可能完整地提供它,以便其他人可以重新生成该问题。我的问题不在于
cufftExecR2C
,而在于内核和下一次迭代的
cudamessetasync
cudamescpyasync
。这些作为计算内核的内部表示可以解释一些事情,但是
cudaMemseAsync
与内核重叠,而
cudaMemcpyAsync
与内核重叠。如果我注释
cudaMemsetAsync
,则所有
cudaMemcpyAsync
都成功重叠。正如问题中所写的代码,memset和memcpy在同一个流中给出,因此它们应该被序列化。是的,它们应该被序列化,但是它们都应该与内核重叠,这需要更多的时间。如果你真的想让所有的并发发生,你需要确保
cuftexecr2c
调用使用的是流,并取消对
cudaStreamSynchronize()
的调用,因为它是同步的。
 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);
 }