【问题标题】:CUDA: Why are bitwise operators sometimes faster than logical operators?CUDA:为什么位运算符有时比逻辑运算符快?
【发布时间】:2012-03-28 11:42:10
【问题描述】:

当我想从内核中榨取最后一点性能时,我通常会发现用位运算符逻辑运算符&&||) /strong> (&|) 使内核更快一点。通过查看 CUDA Visual Profiler 中的内核时间摘要可以观察到这一点。

那么,为什么在 CUDA 中按位运算符比逻辑运算符更快?我必须承认,它们并不总是更快,但很多时候确实如此。我想知道什么魔法可以让这个加速。

免责声明:我知道逻辑运算符短路和位运算符没有。我很清楚这些运算符如何被滥用而导致错误的代码。只有当结果逻辑保持不变、有加速并且因此获得的加速对我来说很重要时,我才会谨慎使用此替换:-)

【问题讨论】:

  • 感谢您提供出色的优化提示!
  • 罗杰:很高兴能帮上忙!当我也发现这一点时,我感到很惊讶:-)

标签: cuda bitwise-operators logical-operators


【解决方案1】:

逻辑运算符通常会导致分支,尤其是在需要遵守短路评估规则时。对于普通 CPU,这可能意味着分支预测错误,而对于 CUDA,这可能意味着扭曲发散。按位运算不需要短路评估,因此代码流是线性的(即无分支)。

【讨论】:

  • 另外,对于逻辑运算符,非零结果必须设置为 1。
  • @Roger: 是的,但这通常可以优化掉,例如如果表达式只是被用作条件的一部分 - 如果它被分配给一个变量,结果只需要设置为 1。
【解决方案2】:

A && B:

if (!A) {
  return 0;
}
if (!B) {
  return 0;
}
return 1;

A 和 B:

return A & B;

考虑到评估 A 和 B 可能会产生副作用(它们可以是在评估时改变系统状态的函数),这些是语义。

编译器可以通过多种方式优化A && B 的情况,具体取决于A 和B 的类型以及上下文。

【讨论】:

    【解决方案3】:

    可以在硬件级别的寄存器中执行按位运算。寄存器操作是最快的,当数据可以放入寄存器时尤其如此。逻辑运算涉及可能不受寄存器限制的表达式评估。通常 &、|、^、>>... 是一些最快的操作,并广泛用于高性能逻辑。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-07-03
      • 2020-04-07
      • 2014-07-01
      • 1970-01-01
      • 2012-07-16
      • 2018-06-07
      • 1970-01-01
      相关资源
      最近更新 更多