读书人

linux内核中的likely跟unlikely

发布时间: 2013-01-21 10:15:39 作者: rapoo

linux内核中的likely和unlikely

linux内核中的likely和unlikely

Kernel version:2.6.14

CPU architecture:ARM920T

Author:ce123(http://blog.csdn.net/ce123)

GCC version:arm-linux-gcc-3.4.1

看内核时经常遇到if(likely( )){}或是if(unlikely( ))这样的语句,不甚了解,例如(选自kernel/fork.c中copy_process):

00008460 <test_likely>:    8460:e3500000 cmpr0, #0; 0x0    8464:03a00006 moveqr0, #6; 0x6    8468:13a00005 movner0, #5; 0x5    846c:e1a0f00e movpc, lr00008470 <test_unlikely>:    8470:e3500000 cmpr0, #0; 0x0    8474:03a00006 moveqr0, #6; 0x6    8478:13a00005 movner0, #5; 0x5    847c:e1a0f00e movpc, lr

如上述例子分析所示,两个函数编译生成的汇编语句所使用到的跳转指令不一样,仔细分析下会发现__builtin_expect实际上是为了满足在大多数情况不执行跳转指令,__builtin_expect仅仅是告诉编译器优化,并没有改变其对真值的判断。宏likely和宏unlikely唯一的作用就是选择”将if分支还是else分支放在跳转指令之后,从而优化程序的执行效率”。 因为likely(EXP)代表条件表达式EXP很可能成立,而unlikely(EXP)代表条件表达式EXP很可能不成立,当程序员清楚EXP表达式 多数情况成立(不成立)时,就可使用likely(unlikely),使if分支(else分支)紧跟跳转指令其后,从而在大多数情况下不用执行跳转指令,避开跳转指令所带来的开销,从而达到优化的目的。

还有一点需要注意的是,在生成汇编时用的是arm-linux-gcc -fprofile-arcs -O2 -c test_builtin_expect.c,而不是arm-linux-gcc -O2 -c test_builtin_expect.c。

读书人网 >UNIXLINUX

热点推荐