对于CUDA中的简单的warp内线程分歧,我所知道的是SM选择了一个重新收敛点(PC地址),并在两个/多个路径中执行指令,同时禁止执行对于避免&#39的线程的执行走了路。
例如,在下面的代码中:
if( threadIdx.x < 16 ) {
A:
// do something.
} else {
B:
// do something else.
}
C:
// rest of code.
C
是重新收敛点,warp调度程序会同时调度A
和B
上的指令,同时禁用A
处的指令用于上半经线和禁用指令在B
处获得较低的半翘曲。当它到达C
时,将为warp中的所有线程启用指令。
我的问题是SM是否能像上面那样正确处理包含goto
指令的代码?或者不能保证选择的再收敛点是最佳的?
例如,如果我在使用goto
A:
// some code here.
B:
// some code here too.
if( threadIdx.x < 16 ) {
C:
// do something.
goto A;
}
// do something else.
goto B;
SM是否足够聪明,可以将B
作为if
指令引起的经线内发散的重新收敛点?
答案 0 :(得分:2)
通常,goto
是非结构化控制流,它会干扰许多编译器优化,无论平台如何。 CUDA C编译器应以功能正确的方式处理goto
的代码,但性能可能不是最理想的。
部分次优性能可能是编译器的汇聚点位置。您可以使用cuobjdump --dump-sass
检查生成的机器代码(SASS)中的收敛点。 SSY
指令记录收敛点,指令上的.S
后缀表示控制转移到最后记录的收敛点。