在linux kernel源码里经常可以看到likely与unlikely这两个关键字的使用,查了下源码,原来这两个关键字是两个宏。
方法/步骤
1
在linux kernel源码里经常可以看到likely与unlikely这两个关键字的使用,查了下源码,原来这两个关键字是两个宏,在kernel源码的include/linux/compiler.h文件中有如下定义(linux-3.11.0-rc1):
2
由于CONFIG_PROFILE_ALL_BRANCHES没有定义,故而两个宏对应的定义如下:
3
# define likely(x) __builtin_expect(!!(x), 1)# define unlikely(x) __builtin_expect(!!(x), 0)
4
其中,__builtin_expect为gcc的一个内建函数,主要是提供分支选择的优化,将条件成立后会执行的代码段放置判断条件后面,以便优化代码的二进制内容,紧凑招待的代码,让代码执行效率更高,避免过多跳转造成的低效率。
5
例如:
6
if (__builtin_expect(!!(x), 1)) { A } else { B }
7
从代码的代码看,表示条件为真的概率会更高,程序大部分会执行A代码段,而如果将1改为0,那么程序则会大多数情况下执行B代码段。
8
将上面的条件转换为likely(x)和unlikely(x),则刚好与上面的分析对应上了,但是上面的宏中有!!(x),这又是什么作用呢?
9
主要是看后面的判断对比数值为0或1,此处是将传进来的x取非转换为布尔型,再取反恢复为原来x对应到布尔值,即以0和1来表示false和true的形式,因为非零值会认为是true,但此处将非零值拿来与1判断时,难以确认其为true,故而两次取反后缩小判断值来实现布尔判断。END