c++ - 通过按位选择删除分支

标签 c++ optimization

我被告知代码中的分支

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/

相关文章:

c++ - 我如何链接到 Lua 中的回调函数,以便在重新加载脚本时更新回调?

c++ - 为什么 valarray 分配不根据文档调整受让人的大小?

numpy - 加速矩阵求逆

javascript - 加载 JavaScript

c# - 执行从 C# 到 MySQL 的 INSERT 语句的正确方法

python - swig c++ 到 python 通过引用返回 unsigned char*

c++ - 如何重置 QGraphicsView 中的比例?

objective-c - 向 MKMapView 添加注释的最佳方式

sql - 您的解释计划中的 PARTITION RANGE ALL 不好吗?

c++ - Windows 上的快速计数信号量?