【问题标题】:How to reduce CUDA synchronize latency / delay如何减少 CUDA 同步延迟/延迟
【发布时间】:2012-08-10 19:53:10
【问题描述】:

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

在CUDA中有很多同步命令 cudaStream同步, CudaDeviceSynchronize, cudaThread同步, 还有 cudaStreamQuery 来检查流是否为空。

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

还有没有什么数字可以判断最有效的同步方法。也就是说,考虑在一个应用程序中使用 3 个流,其中两个需要完成才能让我启动第四个流,我应该使用 2 个 cudaStreamSyncs 还是只使用一个 cudaDeviceSync 什么会减少损失?

【问题讨论】:

  • cudaThreadSynchronize 已弃用。

标签: concurrency cuda latency synchronize cuda-streams


【解决方案1】:

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

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

可以通过调用cudaSetDeviceFlags()cudaDeviceScheduleBlockingSync 或调用cudaEventCreate()cudaEventBlockingSync 来请求“阻止”。阻塞等待导致驱动程序将命令插入 DMA 命令缓冲区,当缓冲区中的所有先前命令都已执行时,该命令会发出中断信号。然后,驱动程序可以将中断映射到 Windows 事件或 Linux 文件句柄,从而使同步命令能够等待而不会像默认轮询方法那样不断烧毁 CPU。

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

【讨论】:

  • 听起来轮询和阻塞的区别在于轮询会消耗CPU时间,而阻塞不会。但是,同步发生所需的时间没有差异。在 CPU 没有工作要做的情况下,它们会简化为相同的事情。对吗?
  • 可能存在时间差异,因为中断处理会增加延迟。因此,为了换取在轮询时不消耗 CPU,您需要支付更长的等待时间和线程因此而解除阻塞之间的时间。
  • 但是cudaDeviceScheduleBlockingSynccudaDeviceScheduleYield 有什么区别? cudaDeviceScheduleYield 如所写:“指示 CUDA 在等待来自设备的结果时让出其线程。这会在等待设备时增加延迟,但可以提高 CPU 线程与设备并行执行工作的性能。” - 即等待结果没有在旋转中烧毁 CPU - 即“阻塞”。还有cudaDeviceScheduleBlockingSync - 等待结果而不会在旋转中烧毁CPU。但是有什么区别呢?
  • yield选项轮询(重复读取一个内存位置),但在轮询过程中调用SwitchToThread等函数以减少CPU开销。 msdn.microsoft.com/en-us/library/windows/desktop/…
猜你喜欢
  • 1970-01-01
  • 2018-04-10
  • 2018-09-06
  • 1970-01-01
  • 2019-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多