likely&unlikely

2013年1月10日 | 分类: 操作系统, 编程技术 | 标签:

读haproxy的代码的时候,经常看到likely,unlikely的使用,代码中的定义是:

#define likely(x) (__builtin_expect((x) != 0, 1))  
#define unlikely(x) (__builtin_expect((x) != 0, 0))   

这个宏定义主要是告诉编译器x变量更可能是1或者是0,方便编译器进行分支优化,__builtin_expect是gcc的一个宏,并没有改变变量x的值。
例如,程序:

#define LIKELY(x) __builtin_expect((x) != 0, 1)  
#define UNLIKELY(x) __builtin_expect((x) != 0, 0)  
int test_likely(int x)  
{  
        if(LIKELY(x))  
        {  
                x=2;  
        }  
        else  
        {  
                x=3;  
        }  
        return x;  
}  
int test_unlikely(int x)  
{  
        if(UNLIKELY(x))  
        {  
                x=2;  
        }  
        else  
        {  
                x=3;  
        }  
        return x;  
}  

编译并查看其汇编代码:
gcc -fprofile-arcs -O2 -c like.c
objdump -d like.o

0000000000000000 <test_unlikely>:
   0:   48 83 05 00 00 00 00    addq   $0x1,0(%rip)        # 8 <test_unlikely+0x8>
   7:   01 
   8:   85 ff                   test   %edi,%edi
   a:   75 0e                   jne    1a <test_unlikely+0x1a> 此处不成立可能性更大
   c:   48 83 05 00 00 00 00    addq   $0x1,0(%rip)        # 14 <test_unlikely+0x14>
  13:   01 
  14:   b8 03 00 00 00          mov    $0x3,%eax
  19:   c3                      retq   
  1a:   48 83 05 00 00 00 00    addq   $0x1,0(%rip)        # 22 <test_unlikely+0x22>
  21:   01 
  22:   b8 02 00 00 00          mov    $0x2,%eax
  27:   c3                      retq   
  28:   0f 1f 84 00 00 00 00    nopl   0x0(%rax,%rax,1)
  2f:   00 

0000000000000030 <test_likely>:
  30:   48 83 05 00 00 00 00    addq   $0x1,0(%rip)        # 38 <test_likely+0x8>
  37:   01 
  38:   85 ff                   test   %edi,%edi
  3a:   74 0e                   je     4a <test_likely+0x1a> 此处成立可能性较大
  3c:   48 83 05 00 00 00 00    addq   $0x1,0(%rip)        # 44 <test_likely+0x14>
  43:   01 
  44:   b8 02 00 00 00          mov    $0x2,%eax
  49:   c3                      retq   
  4a:   48 83 05 00 00 00 00    addq   $0x1,0(%rip)        # 52 <test_likely+0x22>
  51:   01 
  52:   b8 03 00 00 00          mov    $0x3,%eax
  57:   c3                      retq   
  58:   0f 1f 84 00 00 00 00    nopl   0x0(%rax,%rax,1)

更多参考http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html

本文的评论功能被关闭了.