2012-08-14 147 views
7

这个问题是关系到使用CUDA流运行多个内核如何减少CUDA同步延迟/延缓

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

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

也有任何数字来判断最有效的同步方法。那就是考虑在应用程序中使用3个流,并且其中两个需要为我完成以启动第四个流,如果我使用2个cudaStreamSyncs或者只有一个cudaDeviceSync,会导致更少的损失?

+1

cudaThreadSynchronize已弃用。 – 2012-08-15 03:27:28

回答

8

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

“轮询”是驱动程序等待GPU的默认机制 - 它等待32位内存位置达到GPU写入的某个值。等待结束后,它可能会更快地返回等待状态,但在等待期间,它会烧毁一个CPU内核来查看该内存位置。

可以通过拨打cudaSetDeviceFlags()cudaDeviceScheduleBlockingSync或拨打cudaEventCreate()cudaEventBlockingSync来请求“阻止”。阻塞等待会导致驱动程序向DMA命令缓冲区中插入一条命令,以便在缓冲区中的所有前面的命令执行完成时发出中断信号。然后,驱动程序可以将中断映射到Windows事件或Linux文件句柄,从而使同步命令可以在不中断CPU的情况下等待,就像缺省轮询方法一样。

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

+0

这听起来像轮询和阻塞之间的区别是轮询烧伤CPU时间和阻止不。但是,同步发生的时间没有区别。在CPU没有完成工作的情况下,它们会减少到同样的程度。那是对的吗 ? – shadow 2012-08-16 09:44:58

+0

可能会有时间差异,因为中断处理会增加延迟。因此,为了在轮询中不烧CPU,您需要花费更长的时间来等待解决的等待和线程解锁。 – ArchaeaSoftware 2012-08-16 14:41:54

+0

但'cudaDeviceScheduleBlockingSync'和'cudaDeviceScheduleYield'有什么区别? 'cudaDeviceScheduleYield'写成如下:“指示CUDA在等待设备结果时产生其线程,这可能会增加等待设备时的等待时间,但可以提高与设备并行工作的CPU线程的性能。” - 即等待结果**,而不是在旋转中烧坏CPU - 即“阻塞”。并且'cudaDeviceScheduleBlockingSync'也是 - 等待结果,而不会烧掉CPU中的旋转。但有什么区别? – Alex 2014-03-15 12:46:32