如果知道warp中所有线程的条件相同,如何避免在CUDA程序中执行条件的两个分支?
Posted
技术标签:
【中文标题】如果知道warp中所有线程的条件相同,如何避免在CUDA程序中执行条件的两个分支?【英文标题】:How to avoid executing both branches of conditional in CUDA program if it is known that the condition is the same for all threads in a warp? 【发布时间】:2020-12-20 01:08:53 【问题描述】:据我了解,如果我有以下形式的 CUDA 代码:
if (condition)
// do x
else
//do y
然后由于线程在扭曲中的 SIMT 执行,条件的执行将被序列化,并且所有线程都需要运行代码的 x 和 y 部分。例外情况是如果分支很大,在这种情况下编译器会使用__any
插入检查以避免不必要地运行代码。
但是,如果我提前知道一个 warp 中的所有线程都将具有相同的 condition
值,那么这个 __any
操作就没有必要了,只会降低我的代码速度。
我想知道是否有任何方法可以指示编译器不包含此投票操作,而是假设条件的评估对于 warp 中的所有线程都是相同的,并且只运行相应的块代码?
【问题讨论】:
我对编译器插入__any
的说法持怀疑态度。我在条件的两边都写了复杂的代码,我在 SASS 中看不到它。我知道你可以找到info on the web that seems to substantiate this,但我认为这是过时的信息,以及可能不再正确的实现细节。在任何情况下都没有这样的documented instruction to the compiler,并且warp vote 是一个成本相对较低的指令。
相反,NVIDIA materials(幻灯片 49)建议如果决策边界在扭曲之外,则可以避免分歧的成本(对于该扭曲)。我的理解是,只有当 warp 中的一个或多个线程实际选择了该路径时,warp 执行引擎才会遵循不同的路径。如果 warp 中的 0 个线程选择了特定的发散路径,则 warp 执行引擎足够聪明,不会调度该路径(所有线程都被屏蔽)。
【参考方案1】:
然后由于线程在 warp 中的 SIMT 执行,条件的执行将被序列化,并且所有线程都需要运行代码的 x 和 y 部分
只有当条件在扭曲中的评估不一致时才会发生
如果分支很大,则例外情况,在这种情况下,编译器将使用
__any
插入检查以避免不必要地运行代码。
这是完全错误的。该编译器不这样做,并且从字面上反汇编任何版本的 CUDA 编译器所发出的任何代码都是微不足道的 NVIDIA 曾经发布过以确认这一点。有predicated execution,但这与你描述的有很大不同。
但是,如果我已经提前知道 warp 中的所有线程都将具有相同的条件值,那么这个 __any 操作是不必要的,只是为了减慢我的代码速度。
这不仅没有必要,而且根本不存在。
我想知道是否有任何方法可以指示编译器不包含此投票操作,而是假设条件的评估对于 warp 中的所有线程都是相同的,并且只运行相应的块代码?
不,因为你想要的是默认行为。
【讨论】:
以上是关于如果知道warp中所有线程的条件相同,如何避免在CUDA程序中执行条件的两个分支?的主要内容,如果未能解决你的问题,请参考以下文章