我刚刚阅读了有关动态并行性的文档。我想知道:我可以在内核中使用cudaDeviceSynchronize()
来同步当前在该设备上运行的所有块吗?
文档说:
任何线程的CUDA运行时操作(包括内核启动)都可以在线程块中看到。这意味着父网格中的调用线程可以对该线程,线程块中的其他线程或同一线程块中创建的流启动的网格执行同步。
此外:
在网格中创建的流和事件存在于线程块范围内,但在创建它们的线程块之外使用时具有未定义的行为。
我的问题基本上是 NO 。但是由于cudaDeviceSynchronize()
使用整个设备的全局流,我不确定该流是否可见,并且对于设备上的所有线程是否相同,无论它们属于哪个块或启动。这样我就可以在内核中使用cudaDeviceSynchronize()
进行全局同步。
答案 0 :(得分:5)
没有。无法安全地进行设备范围的同步。
编程指南(Link)的C.3.1.4节:
cudaDeviceSynchronize()函数将同步线程块中任何线程启动的所有工作,直到调用cudaDeviceSynchronize()为止。
它没有说明与其他线程块交互。
一般来说,CUDA中的全局同步会导致问题,因为最常用于填充GPU工作的超额预订方法。要同步的块数通常比设备上的块大得多,因此每个块的上下文必须交换进出全局内存,从而破坏性能。
如果您知道自己有特殊情况,可以使用黑客来解决这个问题,但通常情况下,同步块的最简单,最有效的方法是退出内核并启动新内核。