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

在内核中使用cudaDeviceSynchronize()进行全局同步,cuda,Cuda,我刚刚阅读了关于动态并行性的文档。我想知道的是:我可以在内核中使用cudaDeviceSynchronize()来同步当前在该设备上运行的所有块吗 文件说: 任何线程(包括内核启动)的CUDA运行时操作都可以在线程块中看到。这意味着父网格中的调用线程可以在该线程、线程块中的其他线程或在同一线程块中创建的流上启动的网格上执行同步 此外: 在网格中创建的流和事件存在于线程块范围内,但在创建它们的线程块之外使用时具有未定义的行为 这基本上是对我的问题的否定。但是由于cudaDeviceSynchron

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

文件说:

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

此外:

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


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

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

编程指南()第C.3.1.4节:

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

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

CUDA中的全局同步通常会导致问题,因为最常用于向GPU填充工作的过度订阅方法。要同步的块数通常比设备上适合的块数大得多,因此每个块的上下文必须在全局内存中交换,从而破坏性能


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

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

编程指南()第C.3.1.4节:

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

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

CUDA中的全局同步通常会导致问题,因为最常用于向GPU填充工作的过度订阅方法。要同步的块数通常比设备上适合的块数大得多,因此每个块的上下文必须在全局内存中交换,从而破坏性能

如果你知道你有一个特殊的情况,你可以使用一些黑客来绕过这个问题,但是通常,最简单和最有效的同步块的方法是退出内核并启动一个新的