应对分支预测有哪些优化措施

描述

应对分支预测有哪些优化措施

下面再来看一下分支预测,这也是 ChatGPT 给出的一个简易答案

// 不利于流水线的循环结构
for (int i = 0; i < N; ++i) {
    if (condition) {
        // 循环体
    }
}


// 更有利于流水线的循环结构
if (condition) {
    for (int i = 0; i < N; ++i) {
        // 循环体
    }
}

上面的案例就是说明,我们应该在循还外进行条件判断,这样即便是预测失败概率 10%,也只有 10%的回滚情况,但是如果放到循环体内部,那么这个 10%的回滚操作将被执行 N 次。

除了把判断语句从循环体中挪出来,还有一些小的技巧供大家参考一下。

合并条件,尽可能减少分支预测失败时对效率的影响

优化前:

if(case1){    if( case2 )    {        do();    }}

优化后:

if( case1 && case2 ){    do();}

优化前:

if( case1 == 0 && case2 == 0 && case3 == 0 ){    do();}

优化后:

if( ( case1 | case2 | case3 ) == 0 ){    do();}

跳转避免分支预测

if else改写成switch形式(switch使用的指针 list 进行跳转的指令,直接跳转到对应分支)。这样就相当于将多个函数使用函数指针的形式存储到数组中,然后通过 case 查表,直接进行调用。

直接运算,避免判断

先说明一些基本位运算知识:

|x| > > 31 = 0     // 非负数右移31为一定为0
~(|x| > > 31) = -1 // 0取反为-1


-|x| > > 31 = -1   // 负数右移31为一定为0xffff = -1
~(-|x| > > 31) = 0 // -1取反为0


-1 = 0xffff
-1 & x = x        // 以-1为mask和任何数求与,值不变

如对于

if(value < 0 ) value = 0

可改成

value &= ~(value > > 31 )

再比如:

if (data[c] >= 128){    sum += data[c];}

可以优化为:

int t = (data[c] - 128) >> 31; // 非负数右移 310,负数右移则为 -1sum += ~t & data[c];     // 这里利用 0 和 -1,正好等同于条件,大于 128 忽略,小于 128
打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分