CUDA warp divergence 的小思考
CUDA 的执行是以 warp 为单位的,一个 warp 内的线程的运行像是一排阵列士兵一样齐刷刷地踢正步。warp 扮演的角色就是给这一排士兵下指令的军官。
但是总有例外。比如遇到了线程 id 相关的 if-else,一部分线程走 a 分支,另一部分线程走 b 分支,这就会造成 warp divergence。军官在单位时间内只能下一条指令。为了让士兵完成各自的命令,一个解决方法是:
- 军官下令只让分支 a 的士兵听指令,分支 b 的士兵原地待命。(active mask)
- 军官正常下分支 a 中的命令
- 分支 a 命令结束。下令 a 的士兵待命,b 的士兵听令。
- 军官正常下分支 b 中的命令
- 两分支汇合,过程结束
这个方法的弊端是将两个分支的执行串行化了,非 active 的线程没有完全利用,浪费了性能。
CUDA 早期(pre volta)的 warp divergence 大致是以这样的思路解决的。不过即使是现在的 CUDA,对于这种 divergence 还是会造成一定程度的性能浪费。