cuda - GPU 中的同步

标签 cuda opencl gpu gpgpu nvidia

我有一些关于 GPU 如何执行同步的问题。
据我所知,当一个经线遇到障碍(假设它在 OpenCL 中)时,它知道同一组的其他经线还没有出现。所以它必须等待。但是在等待期间,经线究竟做了什么?
它仍然是一个活跃的经线吗?或者它会做某种空操作?

正如我所注意到的,当我们在内核中进行同步时,指令的数量会增加。我想知道这个增量的来源是什么。同步是否分解为许多较小的 GPU 指令?或者因为空闲扭曲执行一些额外的指令?

最后,我强烈想知道与没有同步的情况相比,同步增加的成本(假设屏障(CLK_LOCAL_MEM_FENCE))是否受工作组(或线程块)中的扭曲数量的影响?
谢谢

最佳答案

事件扭曲是驻留在 SM 上的扭曲,即所有资源(寄存器等)都已分配,并且只要它是可调度的,它就可用于执行。如果一个warp在同一个线程块/工作组中的其他warp之前到达屏障,它仍然是事件的(它仍然驻留在SM上并且它的所有寄存器仍然有效),但它不会执行任何指令,因为它是没有准备好被安排。

插入屏障不仅会停止执行,而且还充当编译器的屏障:不允许编译器跨屏障执行大多数优化,因为这可能会使屏障的目的无效。这是您看到更多指令的最可能原因 - 没有障碍,编译器能够执行更多优化。

屏障的成本在很大程度上取决于您的代码正在做什么,但是每个屏障都会引入一个气泡,其中所有经线必须(有效地)在它们再次开始工作之前变为空闲状态,因此如果您有一个非常大的线程块/工作组那么当然有可能比小块更大的泡沫。气泡的影响取决于您的代码 - 如果您的代码非常受内存限制,那么屏障将暴露内存延迟之前它们可能被隐藏的地方,但如果更加平衡,那么它的影响可能不太明显。

这意味着在一个非常受内存限制的内核中,您最好启动大量较小的块,以便在一个块在屏障上冒泡时可以执行其他块。您需要确保您的占用率因此增加,并且如果您使用块共享内存在线程之间共享数据,则需要进行权衡。

关于cuda - GPU 中的同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6676384/

相关文章:

gpu - 在 Google Colaboratory 中,有没有办法支付更大的 GPU?

c - GPU 卡在 2 秒后重置

java - Java中如何使用OpenGL监控GPU使用情况?

opencv - 映射内存和 gpu::CudaMem 用法

cuda - 如何使用 CUDA Thrust 通过索引列表从矩阵中收集行

opencl - 限制 AMD OpenCL 的 GPU 数量

c++ - 牛顿分形生成

opencl - 内存分配 Nvidia vs AMD

c - 无法链接到 libgfortran.a

cuda - 如何使用 CUDA C 快速重新分组/透视数据?