我被告知代码中的分支
int value = //some number;
if(value > some_other_value)
value *= 23;
else
value -= 5;
可以通过按位掩码消除(以便为代码启用 SIMD 优化):
const int Mask = (some_other_value-value)>>31;
value = ((value * 23)&Mask)|((value-5)&~Mask);
但是,我不明白这是如何工作的(尽管我明白这里使用的是什么操作以及结果在二进制中的样子)。此外,这有多普遍适用?如果原来的代码是这样的呢
if(value & 1 == 1)
value *= 23;
else
value -= 5;
分支删除后的代码还会一样吗?否则,面具的目的是什么,我应该如何制作它?这里发生了什么?
最佳答案
这个有效:
const int Mask = (some_other_value-value)>>31;
value = ((value * 23)&Mask)|((value-5)&~Mask);
掩码成为 some_other_value - value
的符号位 - 类似于:
if (value > some_other_value) mask = -1; else mask = 0;
你可以用你的第二个例子实现同样的事情,使用:
mask = -(value & 1);
因此,-0 = 0,-1 = 所有。
编辑:我还要记住,如果计算变得过于复杂,您将无法从分支版本中获得任何好处,尤其是在分支可合理预测的情况下。
关于c++ - 通过按位选择删除分支,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14584681/