CUDA warp vote 函数,例如 __ any()和 __ all(),是否同步 warp 中的线程?
换句话说,是否可以保证warp 中的所有线程都执行warp vote 函数之前的指令,尤其是操纵谓词的指令?
同步是隐式的,因为 warp 中的线程以锁步方式执行。[*]
依赖此行为的代码称为“warp 同步”。
[*] 如果您认为条件代码会导致扭曲中的线程遵循不同的执行路径,您需要了解更多关于 CUDA 硬件如何工作的信息。发散的条件代码(即条件对某些线程为真但对其他线程不成立的条件代码)导致扭曲中的某些线程被禁用(通过预测或分支同步堆栈),但每个线程仍占用 32 个通道之一在经线中可用。
他们没有。您可以在代码分支中使用扭曲投票功能。如果它们在这种情况下同步,则可能会出现死锁。来自 PTX ISA:
投票
跨线程组投票。句法
vote.mode.pred d, {!}a;
vote.ballot.b32 d, {!}a; // 'ballot' form, returns bitmask
.mode = { .all, .any, .uni };
描述
跨线程中的线程执行源谓词的缩减。目的地 > 谓词值在 warp 中的所有线程中都是相同的。减少模式有:
.all 如果源谓词对于 warp 中的所有活动线程为 True,则为 True。否定源谓词以计算 .none。
.any 如果源谓词对于 warp 中的某些活动线程为 True,则为 True。否定源谓词以计算 .not_all。
.uni 如果源谓词在 warp 中的所有活动线程中具有相同的值,则为真。否定源谓词也会计算 .uni。
在投票表单中,vote.ballot.b32 只是将 predicate 从一个 warp 中的每个线程复制到目标寄存器 d 的相应位位置,其中位位置对应于线程的通道 id。
编辑: 由于 warp 中的线程是隐式同步的,因此您不必手动确保线程在投票发生时正确同步。请注意,对于 __all,只有活动线程参与投票。活动线程是在条件为真时执行指令的线程。这解释了为什么在代码分支中会发生投票。