GPU中的同步

7
我有关于GPU执行同步的一些问题。 据我所知,在一个warp遇到屏障时(假设它在OpenCL中),并且它知道同一组的其他warp还没有到达那里。因此,它必须等待。但在等待期间,这个warp具体会做什么呢? 它仍然是一个活动的warp吗?还是会执行某种无操作?
我注意到,在内核中进行同步时,指令数量会增加。我想知道这种增量的来源是什么。同步是否被分解成许多更小的GPU指令?或者是因为空闲的warp执行了一些额外的指令?
最后,我非常想知道与没有同步(比如barrier(CLK_LOCAL_MEM_FENCE))相比,同步所增加的成本是否受工作组(或线程块)中warp数量的影响? 谢谢。
1个回答

7

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

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

屏障的成本非常依赖于代码正在做什么,但每个屏障引入了一个气泡,在此期间,所有warp必须(有效地)变得空闲,然后再次开始工作,因此,如果您有一个非常大的线程块/工作组,那么当然有一个比小块更大的潜在气泡。气泡的影响取决于您的代码-如果您的代码非常受内存限制,则屏障将暴露内存延迟,而以前可能已经隐藏了它们,但是如果更加平衡,则可能影响不太明显。

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


感谢您提供详细的答案。如果您可以分享从中获取知识的一些文档,那将非常好。我想在我的研究中引用。您能否进一步解释为什么内存绑定内核会暴露内存延迟?据我现在的理解,靠近同步(出现在同步之前)的内存请求应该被某些计算隐藏起来,直到数据到达才会停止。这是正确的吗?另一方面,如果内核不受内存限制,那么同步会暴露什么?指令流水线延迟吗?(假设没有分歧,是的,这一切与分歧有什么关系?) - Zk1001

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接