鲲鹏社区首页
中文
注册
开发者
我要评分
获取效率
正确性
完整性
易理解
在线提单
论坛求助

合理使用分支预测

【说明】 通过使用GCC的build-in function _builtinexpect(GCC v2.96版本引入),将最有可能执行的分支告诉编译器,从而触发编译器对生成指令的顺序调整,从而尽可能发挥CPU指令预取的优势,提高指令Cache的命中率来提高程序性能;

一般的用法:
    #define LIKELY(x) __builtin_expect(!!(x), 1) // x很可能为真
    #define UNLIKELY(x) __builtin_expect(!!(x), 0) // x很可能为假

【注意事项】 由于分支预测机制会影响编译器生成的指令排布,因此,对于场景化的分支需要慎重考虑,避免优化部分场景性能的同时,带来其他场景的恶化;通常地,分支预测机制会用在异常保护、调测功能判决等场景。

【案例】

修改前:将LIKELY修饰“a == 7”判断,
   if (LIKELY(a == 7)) {
       a += 5;
       b++;
   } else {
       a -= 3;
       b--;
   }
以Arm GCC 7.3为例,编译器开-O2优化,生成的汇编代码如下,可以看出,更可能执行的加法分支指令排在前面:
    cmp     w0, #0x7
    b.ne    0x4005ac <main+44>  
    mov     w20, #0xa                       
    mov     w1, #0xc            
    ...
修改后:将UNLIKELY修饰a == 7判断:
   if (UNLIKELY(a == 7)) {
       a += 5;
       b++;
   } else {
       a -= 3;
       b--;
   }
生成的汇编指令如下,可以看出,更可能执行的减法分支指令排在前面:
    cmp     w0, #0x7
    b.eq    0x4005d0 <main+80>  
    sub     w1, w0, #0x3
    mov     w20, #0x8         
    ...