在CUDA设备代码中,以下if-else
语句将导致warp线程之间出现分歧,导致SIMD硬件两次通过。假设Vs
是共享内存中的一个位置。
if (threadIdx.x % 2) {
Vs[threadIdx.x] = 0;
} else {
Vs[threadIdx.x] = 1;
}
我相信当我们有一个if
语句时,也会两次传递 no else
分支。为什么会这样?
if (threadIdx.x % 2) {
Vs[threadIdx.x] = 0;
}
以下if
声明是否会在3次通过中完成?
if (threadIdx.x < 10) {
Vs[threadIdx.x] = 0;
} else if (threadIdx.x < 20) {
Vs[threadIdx.x] = 1;
} else {
Vs[threadIdx.x] = 2;
}
答案 0 :(得分:1)
在GPU上,很可能只有一个带有if-else语句的传递 - 一个谓词传递。该条件将在“then”块中为半个线程打开“不执行任何操作”位,并为“else”块关闭另一半的“不执行任何操作”位。
正如@njuffa指出的那样,这取决于诸如目标架构等参数。
有关详细信息,请参阅:
对于if
主体的第一个具体示例,编译器甚至可能不需要谓词传递,因为它可以被重写为
Vs[threadIdx.x] = (threadIdx.x % 2 ? 0 : 1);
这样你的经线就完全一致了。对于你的最后一个例子 - 它真的取决于,但理论上它也可以由编译器优化为单个不可预测的传递,并且也可能是你将拥有一个预测的单一路径,在三者中的每一个都有不同的预测作用域。