宏likely和unlikely
来源:互联网 发布:泰拉瑞亚远程联机软件 编辑:程序博客网 时间:2024/05/03 07:37
http://my.oschina.net/armsky/blog/15320
likely()与unlikely()在2.6内核中,随处可见,那为什么要用它们?它们之间有什么区别呢?
首先明确:
if (likely(value))等价于if (value)
if (likely(a>b)) {
fun1();
if (unlikely(value))等价于if (value)
也就是说likely()和unlikely()从阅读和理解的角度是一样的。
这两个宏在内核中定义如下:
<linux/compiler>
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
这里的__built_expect()函数是gcc(version >= 2.96)的内建函数,提供给程序员使用的,目的是将"分支转移"的信
息提供给编译器,这样编译器对代码进行优化,以减少指令跳转带来的性能下降。
__buildin_expect((x), 1)表示x的值为真的可能性更大。
__buildin_expect((x), 0)表示x的值为假的可能性更大。
也就是说,使用likely(),执行if后面的语句的机会更大,使用unlikely(),执行else后面的语句机会更大一些。通过这种
方式,编译器在编译过程中,会将可能性更大的代码紧跟着后面的代码,从而减少指令跳转带来的性能上的下降。
比如 :
if (likely(a>b)) {
fun1();
}
这里就是程序员可以确定 a>b 在程序执行流程中出现的可能相比较大,因此运用了likely()告诉编译器将fun1()函数
的二进制代码紧跟在前面程序的后面,这样就cache在预取数据时就可以将fun1()函数的二进制代码拿到cache中。
这样,也就添加了cache的命中率。
同样的,unlikely()的作用就是告诉编译器,a<b 的可能性很小所以这里在编译时,将fun2()的二进制代码尽量
不要和前边的编译在一块。咱们不用对likely和unlikely感到迷惑,须要知晓的就是 if(likely(a>b)) 和 if(a>b)在功能
上是等价的,同样 if(unlikely(a<b)) 和 if(a<b) 的功能也是一样的。不一样的只是他们声称的二进制代码有所不一
样,这一点咱们也可以从他们的汇编代码中看到。总之,likely和unlikely的功能就是添加 cache的命中率,提高系统
执行速度。
http://www.cnblogs.com/dongzhiquan/archive/2013/04/09/3011401.html
宏likely和unlikely
在源码中,宏likely和unlikely 是这么定义的(位于include/linux/compiler.h):
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
要理解宏likely和unlikely ,很明显必须理解__builtin_expect。__builtin_expect是GCC(version>=2.9)引进的宏,其作用就是帮助编译器判断条件跳转的预期值,避免跳转造成时间浪费。拿下面的代码来说:
if (likely(acat == 1)) //表示大多数情况下if里面是真,程序大多数直接执行if里面的程序
而
if (unlikely (thread_memory_magazine1_is_empty (tmem, ix)))//表示大多数情况if里面为假,程序大多数直接执行else里面的程序
两段代码编译生成的汇编语句所使用到的跳转指令不一样,__builtin_expect实际上是为了满足在大多数情况不执行跳转指令,所以__builtin_expect仅仅是告诉编译器优化,并没有改变其对真值的判断。
示例:
//test_builtin_expect.c #define LIKELY(x) __builtin_expect(!!(x), 1)#define UNLIKELY(x) __builtin_expect(!!(x), 0)int test_likely(int x){ if(LIKELY(x)) { x = 5; } else { x = 6; } return x;}int test_unlikely(int x){ if(UNLIKELY(x)) { x = 5; } else { x = 6; } return x;}
[lammy@localhost test_builtin_expect]$ gcc -fprofile-arcs -O2 -c test_builtin_expect.c
[lammy@localhost test_builtin_expect]$ objdump -d test_builtin_expect.o
test_builtin_expect.o: file format elf32-i386
Disassembly of section .text:
00000000 <test_likely>:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 8b 45 08 mov 0x8(%ebp),%eax
6: 83 05 38 00 00 00 01 addl $0x1,0x38
d: 83 15 3c 00 00 00 00 adcl $0x0,0x3c
14: 85 c0 test %eax,%eax
16: 74 15 je 2d <test_likely+0x2d>
//主要看这里
18: 83 05 40 00 00 00 01 addl $0x1,0x40
1f: b8 05 00 00 00 mov $0x5,%eax
24: 83 15 44 00 00 00 00 adcl $0x0,0x44
2b: 5d pop %ebp
2c: c3 ret
2d: 83 05 48 00 00 00 01 addl $0x1,0x48
34: b8 06 00 00 00 mov $0x6,%eax
39: 83 15 4c 00 00 00 00 adcl $0x0,0x4c
40: 5d pop %ebp
41: c3 ret
42: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi
49: 8d bc 27 00 00 00 00 lea 0x0(%edi,%eiz,1),%edi
00000050 <test_unlikely>:
50: 55 push %ebp
51: 89 e5 mov %esp,%ebp
53: 8b 55 08 mov 0x8(%ebp),%edx
56: 83 05 20 00 00 00 01 addl $0x1,0x20
5d: 83 15 24 00 00 00 00 adcl $0x0,0x24
64: 85 d2 test %edx,%edx
66: 75 15 jne 7d <test_unlikely+0x2d>
//主要看这里
68: 83 05 30 00 00 00 01 addl $0x1,0x30
6f: b8 06 00 00 00 mov $0x6,%eax
74: 83 15 34 00 00 00 00 adcl $0x0,0x34
7b: 5d pop %ebp
7c: c3 ret
7d: 83 05 28 00 00 00 01 addl $0x1,0x28
84: b8 05 00 00 00 mov $0x5,%eax
89: 83 15 2c 00 00 00 00 adcl $0x0,0x2c
90: 5d pop %ebp
91: c3 ret
92: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi
99: 8d bc 27 00 00 00 00 lea 0x0(%edi,%eiz,1),%edi
000000a0 <_GLOBAL__I_65535_0_test_likely>:
a0: 55 push %ebp
a1: 89 e5 mov %esp,%ebp
a3: 83 ec 08 sub $0x8,%esp
a6: c7 04 24 00 00 00 00 movl $0x0,(%esp)
ad: e8 fc ff ff ff call ae <_GLOBAL__I_65535_0_test_likely+0xe>
b2: c9 leave
b3: c3 ret
[lammy@localhost test_builtin_expect]$
- likely和unlikely宏
- likely和unlikely宏
- likely和unlikely宏
- 宏likely和unlikely
- likely和unlikely宏
- 内核中的likely和unlikely宏定义
- 内核中的likely和unlikely宏定义
- 内核中的likely和unlikely宏定义
- linux内核中的likely()和unlikely()宏
- 内核中的likely和unlikely宏定义
- linux中likely()和unlikely()宏
- linux宏定义likely和unlikely解析
- 有关likely和unlikely
- 有关likely和unlikely
- 有关likely和unlikely
- 有关likely和unlikely
- likely和unlikely
- likely和unlikely
- 全排列
- 大数乘法
- Android应用程序的获取,安装。
- fatal error C1083: 无法打开预编译头文件:“Debug64\npKq2OaScript.pch”: No such file or directory
- 解决Android解析图片的OOM问题
- 宏likely和unlikely
- CSS样式表初解
- Hadoop集群(第3期)_VSFTP安装配置
- 学习verilog的经典好教材与资料
- Hadoop现有测试框架探幽
- 去掉时间后带的毫秒数
- 西征梦(1)
- TUNE V$UNDOSTAT
- Hadoop集群(第4期)_SecureCRT使用