likely&unlikely
读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
发表评论