在项目中看到了likely、unlikely宏的使用, 一直不是非常清楚它们的作用,所以就深究下。
likely表示被測试的表达式大多数情况下为true, unlikely则表示相反。
 
两个宏定义:
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)这两个宏常常在条件转移的语句中使用,如if, else if等,这些语句生成的汇编代码都带有jmp指令.
依据gcc手冊, 所以这两个宏是用来告诉编译器分支的可能走向,从而帮助CPU进行分支预測来增强CPU流水线性能的.
看下以下的代码
int main (char *argv[], int argc) {
        int v;
        v = atoi(argv[1]);
        if (likely(a == 5))
                a++;
        else
                a--;
        printf("%d\n", a);
        return 0;
}
编译。带上-O2选项,得到的汇编代码:
0000000000400510 <main>:
  400510:       48 83 ec 08             sub    $0x8,%rsp
  400514:       48 8b 7f 08             mov    0x8(%rdi),%rdi
  400518:       31 c0                   xor    %eax,%eax
  40051a:       e8 f1 fe ff ff          callq  400410 <atoi@plt>
  40051f:       83 f8 02                cmp    $0x2,%eax
  400522:       75 18                   jne    40053c <main+0x2c> /* likely在这里表示a非常有可能是2, 所以将运行a++和printf调用放在一起, 免去了jmp带来的影响 */
  400524:       be 03 00 00 00          mov    $0x3,%esi
  400529:       bf 48 06 40 00          mov    $0x400648,%edi
  40052e:       31 c0                   xor    %eax,%eax
  400530:       e8 bb fe ff ff          callq  4003f0 <printf@plt>
  400535:       31 c0                   xor    %eax,%eax
  400537:       48 83 c4 08             add    $0x8,%rsp
  40053b:       c3                      retq
  40053c:       8d 70 ff                lea    -0x1(%rax),%esi
  40053f:       eb e8                   jmp    400529 <main+0x19> /* jump到调用printf代码处, 导致cpu flush掉流水线上的内容. */
  400541:       90                      nop
原文:http://www.cnblogs.com/clnchanpin/p/7093771.html