CUDA编程指南(v4.1)在第5.4.2节中描述了谓词指令:
编译器用谓词替换分支指令 指令仅在指令数量受控制时 分支条件小于或等于某个阈值:如果是 编译器确定条件可能产生很多 发散扭曲,此阈值为7,否则为4。
答案 0 :(得分:2)
变形永远不会“分裂”。它们要么需要“条件执行”(所以执行非参与线程被屏蔽)来服务条件不同的代码路径,要么它们不需要。
至于条件如何产生多个不同的扭曲,请考虑以下设计的例子:
if (threadIdx.x < 128) {
// Only first four warps process here
int modthirtytwo = threadIdx.x % 32;
if (modthirtytwo == 0) {
// Action A only first thread in the warp
} else {
// Action B for the other threads in the warp
}
}
这里,代码可以产生多个不同的warp,编译器应该能够在编译时对行为进行建模。如果为内核的编译器指定了启动边界,那就更好了。将此情况与仅使用一个warp的共享内存减少进行比较。
if (threadIdx.x < 32) {
if (threadIdx.x < 16) shm[threadIdx.x] += shm[threadIdx.x+16];
if (threadIdx.x < 8) shm[threadIdx.x] += shm[threadIdx.x+8];
if (threadIdx.x < 4) shm[threadIdx.x] += shm[threadIdx.x+4];
if (threadIdx.x < 2) shm[threadIdx.x] += shm[threadIdx.x+2];
if (threadIdx.x == 0) shm[0] += shm[1];
}
这里的差异仅限于每个块的单个扭曲。所有这些文字都说是两种情况下的编译器行为可能不同。
似乎“新”编译器(它已经用于OpenCL几年)具有heurisitics,用于在分支变得更经济之前它应该使用多少谓词指令。并且似乎指令管道中的许多分支对性能不利,因此当编译器可以计算出代码将产生更高的“分支密度”时,它将更喜欢更多的谓词指令而不是分支。