假设由单个warp(为简单起见)执行的CUDA内核到达if
- else
语句,其中warp中的20个线程满足condition
和32 - 20 = 12个线程没有:
if (condition){
statement1; // executed by 20 threads
else{
statement2; // executed by 12 threads
}
如果warp的线程经由数据相关的条件分支发散,则warp一次执行一条公共指令,warp串行执行所采用的每个分支路径,禁用不在该路径上的线程,以及当所有路径完成时,线程会聚回到相同的执行路径。
因此,这两个语句将在不同的循环中顺序执行。
Kepler架构每个warp调度程序包含2个指令调度单元,因此能够在每个周期发出每个warp 2个独立指令。
我的问题是:在这个只有两个分支的设置中,为什么statement1
和statement2
不能由两个指令调度单元发出,以便由warp中的32个线程同时执行,即20线程执行statement1
而其他12个线程同时执行statement2
?如果指令调度程序不是warp一次执行单个公共指令的原因,那么它是什么?它是仅提供32线程宽指令的指令集吗?还是硬件相关的原因?
答案 0 :(得分:5)
每个内核指令总是针对warp中的所有线程执行。因此,逻辑上不可能同时在同一个warp中的不同线程上执行不同的指令。这将违背构建GPU的SIMT execution model。对于你的问题:
Kepler架构每个warp调度程序包含2个指令调度单元,因此每个warp能够在每个周期发出2个独立指令。
...
为什么statement1和statement2不能由两个指令调度单元发出,以便由warp中的32个线程同时执行,即20个线程执行statement1而其他12个线程同时执行statement2?
我不确定您是否意识到这一点,但如果statement1
和statement2
在计算上独立,那么它们可以在一个周期内执行:
statement1
的说明将在所有主题上执行,statement2
的指令将在同一周期内的所有线程上执行,这要归功于第二个调度单元。一般来说,分支差异如何在GPU中起作用,可以找到一些进一步的读数。 here。因此,我相信您已经免费获得了您的要求 - 两个语句都在同一个周期内执行(或可以)。
修改强>
正如评论中所述的talonmies,值得一提的是条件执行,因为它有时有助于防止分支分歧的惩罚。可以找到关于该主题的更多信息。在this SO thread中,引用:
对于更简单的条件,NVIDIA GPU支持ALU的条件评估,这不会引起分歧,对于整个warp遵循相同路径的条件,显然也没有惩罚。