CUDA:避免分支分歧上的串行执行
CUDA: Avoiding serial execution on branch divergence
假设由单个warp执行的CUDA内核(为简单起见)达到if
-else
语句,其中warp中的20个线程满足condition
,32-20=12个线程不满足:
if (condition){
statement1; // executed by 20 threads
else{
statement2; // executed by 12 threads
}
根据CUDA C编程指南:
warp一次执行一条公共指令[…]如果warp的线程通过依赖数据的条件分支分叉,warp会串行执行所采用的每个分支路径,禁用不在该路径上的线程,当所有路径完成时,线程会聚合回同一执行路径。
因此,这两条语句将在不同的周期中依次执行。
开普勒体系结构包含每个warp调度器2个指令调度单元,因此能够在每个周期为每个warp发布2个独立的指令。
我的问题是:在这个只有两个分支的设置中,为什么statement1
和statement2
不能由两个指令调度单元发出,以便由warp内的32个线程同时执行,即20个线程执行statement1
,而其他12个线程则同时执行statement2
?如果指令调度程序不是warp一次执行单个公共指令的原因,那是什么?它是只提供32个线程范围指令的指令集吗?还是硬件相关的原因?
每个内核指令总是为warp中的所有线程执行。因此,在逻辑上不可能在同一时间对同一经线内的不同线程执行不同的指令。这将与构建GPU所依据的SIMT执行模型背道而驰。回答您的问题:
开普勒体系结构每个warp调度器包含2个指令调度单元,因此能够在每个周期为每个warp发出2个独立的指令。
为什么语句1和语句2不能由两个指令调度单元发出,以便由warp内的32个线程同时执行,即20个线程执行语句1,而其他12个线程同时运行语句2?
我不确定你是否意识到了这一点,但如果statement1
和statement2
在计算上是独立的,那么它们可以在一个周期内执行:
- 来自CCD_ 10的指令将在所有线程上执行
- 由于有了第二个调度单元,来自
statement2
的指令将在调度的同一周期内在所有线程上执行
这就是GPU中分支分歧的一般工作方式,可以在这里找到一些进一步的解读。因此,我相信你已经免费得到了你想要的东西——这两个语句都在同一个周期内执行(或者可以)。
编辑:
正如talonmies在评论中所说,有条件执行可能值得一提,因为它有时有助于防止分支分歧造成的处罚。关于这个主题的更多信息可以找到,例如在这个SO线程中,引用:
对于更简单的条件,NVIDIA GPU支持ALU处的条件求值,这不会导致发散,对于整个warp遵循相同路径的条件,显然也没有惩罚。
- 在执行其他功能的同时播放动画(LED矩阵和Arduino/ESP8266)
- C++,系统无法执行指定的程序
- 使用C++中的模板和运算符重载执行矩阵运算
- 创建一个函数以在输入为负数或零时输出字符串.第一次执行用户定义的函数
- 执行函数时导致崩溃的变量
- IPC使用多个管道和分支进程来运行Python程序
- 无论条件是否为true,if总是在c++中执行
- 当函数模板参数是具有默认参数的类模板时,函数模板参数的推导如何执行
- 在C++中对T*类型执行std::move的意外行为
- 使用QProcess执行命令,并将结果存储在QStringList中
- 如何在没有信号的情况下从C++执行QML插槽
- 如何确认我的constexpr表达式实际上已经在编译时执行
- C++17中的并行执行策略
- QML按钮点击功能执行顺序
- 程序在执行程序的其余部分之前退出
- 如何删除peer if else分支中的冗长句子
- 为什么catch中的代码没有被执行
- 如何确保在使用基于布尔值的两个方法之一调用方法时避免分支预测错误
- C++从其他 constexpr 创建 lambda 不能按顺序执行 Constexpr
- CUDA:避免分支分歧上的串行执行