当我要从内核中挤出最后一点性能时,我通常会发现用逻辑运算符(&&
和||
) >按位运算符(&
和|
)使内核更快一点。通过查看CUDA Visual Profiler中的内核时间摘要来观察到这一点。
那么,为什么按位运算符更快比CUDA中的逻辑运算符更快?我必须承认,他们并不总是更快,但很多时候他们都是。我想知道什么魔法可以加速。
免责声明:我知道逻辑运算符短路和按位运算符不会。我很清楚如何滥用这些操作符导致错误的代码。我只是在结果逻辑保持不变的情况下小心使用这个替换,加速并且由此获得的加速对我来说很重要: - )
答案 0 :(得分:12)
逻辑运算符通常会产生分支,特别是在需要遵守短路评估规则时。对于普通的CPU,这可能意味着分支错误预测,对于CUDA,它可能意味着扭曲分歧。按位运算不需要短路评估,因此代码流是线性的(即无分支)。
答案 1 :(得分:7)
A&& B:
if (!A) {
return 0;
}
if (!B) {
return 0;
}
return 1;
A& B:
return A & B;
考虑到评估A和B可能有副作用(它们可以是在评估时改变系统状态的函数),这些是语义。
编译器可以通过多种方式优化A && B
情况,具体取决于A和B的类型以及上下文。
答案 2 :(得分:1)
按位操作可以在硬件级别的寄存器中执行。寄存器操作是最快的,当数据适合寄存器时尤其如此。逻辑运算涉及表达式评估,这可能不是寄存器绑定的。通常,&,|,^,>> ...是一些最快的操作,并广泛用于高性能逻辑。