在内核中使用cudaDeviceSynchronize()进行全局同步

时间:2015-07-30 08:26:33

标签: cuda

我刚刚阅读了有关动态并行性的文档。我想知道:我可以在内核中使用cudaDeviceSynchronize()来同步当前在该设备上运行的所有块吗?

文档说:

  

任何线程的CUDA运行时操作(包括内核启动)都可以在线程块中看到。这意味着父网格中的调用线程可以对该线程,线程块中的其他线程或同一线程块中创建的流启动的网格执行同步。

此外:

  

在网格中创建的流和事件存在于线程块范围内,但在创建它们的线程块之外使用时具有未定义的行为。

我的问题基本上是 NO 。但是由于cudaDeviceSynchronize()使用整个设备的全局流,我不确定该流是否可见,并且对于设备上的所有线程是否相同,无论它们属于哪个块或启动。这样我就可以在内核中使用cudaDeviceSynchronize()进行全局同步。

1 个答案:

答案 0 :(得分:5)

没有。无法安全地进行设备范围的同步。

编程指南(Link)的C.3.1.4节:

  

cudaDeviceSynchronize()函数将同步线程块中任何线程启动的所有工作,直到调用cudaDeviceSynchronize()为止。

它没有说明与其他线程块交互。

一般来说,CUDA中的全局同步会导致问题,因为最常用于填充GPU工作的超额预订方法。要同步的块数通常比设备上的块大得多,因此每个块的上下文必须交换进出全局内存,从而破坏性能。

如果您知道自己有特殊情况,可以使用黑客来解决这个问题,但通常情况下,同步块的最简单,最有效的方法是退出内核并启动新内核。