如何减少CUDA同步延迟/延迟

时间:2012-08-14 13:48:41

标签: concurrency cuda latency synchronize cuda-streams

这个问题与使用cuda流来运行许多内核有关

在CUDA中有许多同步命令 cudaStreamSynchronize, CudaDeviceSynchronize, 的cudaThreadSynchronize, 还有cudaStreamQuery来检查流是否为空。

我注意到在使用分析器时,这些同步命令会给程序带来很大的延迟。我想知道是否有人知道减少这种延迟的任何方法,当然除了使用尽可能少的同步命令。

还有任何数字来判断最有效的同步方法。考虑在应用程序中使用3个流,如果我使用2个cudaStreamSyncs或只使用一个cudaDeviceSync,那么其中两个需要完成才能启动第四个流,这会减少损失吗?

1 个答案:

答案 0 :(得分:9)

同步方法之间的主要区别是“轮询”和“阻止”。

“轮询”是驱动程序等待GPU的默认机制 - 它等待32位内存位置以获得GPU写入的特定值。在等待解决后,它可能会更快地返回等待,但在等待时,它会烧毁查看该内存位置的CPU核心。

可以通过cudaSetDeviceFlags()致电cudaDeviceScheduleBlockingSync或使用cudaEventCreate()致电cudaEventBlockingSync来申请“停止”。阻塞等待会导致驱动程序将命令插入DMA命令缓冲区,该命令缓冲区在执行缓冲区中的所有前面的命令时发出中断信号。然后,驱动程序可以将中断映射到Windows事件或Linux文件句柄,使同步命令在不经常刻录CPU的情况下等待,默认轮询方法也是如此。

查询基本上是手动检查用于轮询等待的32位内存位置;所以在大多数情况下,它们非常便宜。但是如果启用了ECC,查询将进入内核模式以检查是否存在ECC错误;在Windows上,任何挂起的命令都将被刷新到驱动程序(这需要内核thunk)。