在GPU编程中使用条件时,工作项执行什么?

Rog*_*ger 7 cuda gpu gpgpu opencl gpu-programming

如果您在波前执行工作项并且存在条件,例如:

  if(x){
        ...
  }
  else{
       ....
  }
Run Code Online (Sandbox Code Playgroud)

工作项执行什么?是这样的情况,波前的所有工作项都将执行第一个分支(即x == true).如果没有x为false的工作项,则跳过其余的条件?

如果一个工作项采用替代路径会发生什么.我是否告诉所有工作项也将执行备用路径(因此执行两个路径?).为什么会出现这种情况,以及如何解决程序执行问题

tal*_*ies 14

NVIDIA gpus使用条件执行来处理SIMD组内的分支差异("warp").在您的if..else示例中,两个分支都由分叉warp中的每个线程执行,但是那些不遵循给定分支的线程被标记并执行null操作.这是经典的分支差异惩罚 - interwarp分支差异需要两次通过代码部分才能退出为warp.这并不理想,这就是面向性能的代码试图最小化这一点的原因.经常引人注意的一件事就是假设分歧路径的哪个部分"先"执行.由于第二次猜测在不同的扭曲中执行的内部顺序,导致了一些非常微妙的错误.

对于更简单的条件,NVIDIA GPU支持ALU的条件评估,这不会引起分歧,对于整个warp遵循相同路径的条件,显然也没有惩罚.

  • 请记住,这些是有效的SIMD或矢量机器,因此您有一个指令发布单元为多个ALU供电.前提是对于典型的计算和渲染工作负载而言,这些工作负载不是非常"分支",这是晶体管预算的最佳用途.添加分支预测之类的东西会使晶体管远离其他东西.执行计算的现代CPU的部分非常小,并且指令处理和高速缓存在管芯区域占主导地位.所以有选择,GPU采用与gern不同的路径 (3认同)
  • 事实上,NVIDIA方法为每个warp使用执行掩码,并确定执行哪些线程.但结果是,使用屏蔽线程调度的ALU相当于NOP.NVIDIA显卡上的实际执行顺序是未定义的,但是一些聪明的微基准测试表明,示例的"else"部分在当前硬件上的"if"部分之前执行.这捕获了许多天真设计的关键部分和自旋内存事务构建的自旋锁.... (2认同)