在调用cudaMemcpyAsync时何时可以安全地重用CPU缓冲区?

时间:2013-04-17 12:32:23

标签: cuda

我的项目将有多个线程,每个线程在不同的cudaStream上发出内核执行。其他一些线程将使用存储在队列中的结果。这里有一些伪代码:

while(true) {
  cudaMemcpyAsync(d_mem, h_mem, some_stream) 
  kernel_launch(some_stream)
  cudaMemcpyAsync(h_queue_results[i++], d_result, some_stream)
}

在第一个cudaMemcpyAsync返回后重用h_mem是否安全?或者我应该使用N个主机缓冲区来发出gpu计算?

如何知道何时可以重用h_mem?我应该使用cudaevents进行一些同步吗?

顺便说一句。 h_mem是主机固定的。如果它是可分页的,我可以重新使用h_mem吗?从我在这里看到的,似乎我可以在memcpyasync返回后重新使用,我是对的吗?

  

异步

     

用于从可分页主机内存到设备内存,主机内存的传输   被立即复制到临时缓冲区(没有设备同步   执行)。一旦可分页缓冲区有,该函数将返回   已复制到暂存内存。 DMA转移到最终   目的地可能尚未完成。用于固定主机之间的传输   内存和设备内存,该功能完全异步。对于   从设备内存传输到可分页的主机内存,该功能   只有在副本完成后才会返回。对于所有其他转移,   该函数是完全异步的。如果必须首先是可分页内存   分阶段固定内存,这将与a异步处理   工人线程。对于从任何主机内存到任何主机内存的传输,   该功能与主机完全同步。

MemcpyAsynchronousBehavior

谢谢!

1 个答案:

答案 0 :(得分:1)

为了获得复制/计算重叠,您必须使用固定内存。其原因包含在您摘录的段落中。大概是你的多流方法的全部原因是复制/计算重叠,所以我不认为正确的答案是切换到使用可分页的内存缓冲区。

关于您的问题,假设h_mem仅用作您在此处显示的伪代码的源缓冲区(即其中的数据仅参与那一个cudaMemcpyAsync调用) ,一旦该流中的 next cuda操作开始,则不再需要h_mem缓冲区。因此,如果您的kernel_launch是实际kernel<<<...>>>(...),那么一旦kernel开始,您就可以确信之前的cudaMemcpyAsync已完成。

您可以将cudaEvents与cudaEventSynchronize()cudaStreamWaitEvent()一起使用,也可以直接在流中使用cudaStreamSynchronize()。例如,如果您在已显示的流伪代码中的某处有cudaStreamSynchronize()调用,并且它位于cudaMemcpyAsync调用之后,那么cudaStreamSynchronize()调用之后的任何代码都将保证正在执行cudaMemcpyAsync()电话完成后。我引用的所有电话都记录在usual place