在 2.6 内核中,随处能够见到 likely() 和 unlikely() 的身影,那么为什么要用它们?它们之间有什么差别?

首先要明白:

     if(likely(value)) 等价于 if(value)

     if(unlikely(value)) 也等价于 if(value)

也就是说 likely() 和 unlikely() 从阅读和理解代码的角度来看。是一样的!。!

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

__builtin_expect() 是 GCC (version >= 2.96)提供给程序猿使用的,目的是将“分支转移”的信息提供给编译器,这样编译器能够对代码进行优化。以降低指令跳转带来的性能下降。

__builtin_expect((x),1) 表示 x 的值为真的可能性更大;

__builtin_expect((x),0) 表示 x 的值为假的可能性更大。

也就是说,使用 likely() ,运行 if 后面的语句 的机会更大,使用unlikely(),运行else 后面的语句的机会更大。

比如以下这段代码,作者就觉得 prev 不等于 next 的可能性更大,

if (likely(prev != next)) {
next->timestamp = now;
...
} else {
...;
}

通过这样的方式,编译器在编译过程中,会将可能性更大的代码紧跟着起面的代码,从而降低指令跳转带来的性能上的下降。

另外内核2.6.31.5中likely和unlikely另一种定义:
# ifndef likely
# define likely(x) (__builtin_constant_p(x) ? !!(x) : __branch_check__(x, 1))
# endif # ifndef unlikely
# define unlikely(x) (__builtin_constant_p(x) ? !!(x) : __branch_check__(x, 0))
# endif

举个样例(内核版本号2.6.22.6):/kernel/shed.c中有一段:

if (likely(!active_balance)) {
/* We were unbalanced, so reset the balancing interval */
sd->balance_interval = sd->min_interval;
} else {
/*
* If we've begun active balancing, start to back off. This
* case may not be covered by the all_pinned logic if there
* is only 1 task on the busy runqueue (because we don't call
* move_tasks).
*/
if (sd->balance_interval max_interval)
sd->balance_interval *= 2;
}

编译过程中,会将if后面{}里的内容编译到前面。else 后面{}里的内容编译到后面。若将likely换成unlikely 则正好相反。

总之,likely与unlikely互换或不用都不会影响程序的正确性。

但可能会影响程序的效率。

Linux 内核中 likely 与 unlikely 的宏定义解析的更多相关文章

  1. Linux内核中的fastcall和asmlinkage宏

    代码中看见:#define _fastcall 所以了解下fastcall -------------------------------------------------------------- ...

  2. 《linux 内核全然剖析》 笔记 CODE_SPACE 宏定义分析

    在memory.c里面.遇到一个宏定义,例如以下: #define CODE_SPACE(addr) ((((addr)+4095)&~4095) < \ current->sta ...

  3. Linux内核中_IO,_IOR,_IOW,_IOWR宏的用法与解析【转】

    转自:http://blog.csdn.net/hzn407487204/article/details/7995041 在驱动程序里, ioctl() 函数上传送的变量 cmd 是应用程序用于区别设 ...

  4. Linux内核中_IO,_IOR,_IOW,_IOWR宏的用法与解析

    ref from : http://blog.csdn.net/zhuxiaoping54532/article/details/49680537 main 在驱动程序里, ioctl() 函数上传送 ...

  5. Linux内核中_IO,_IOR,_IOW,_IOWR宏的用法

    #define _IO(type,nr)        _IOC(_IOC_NONE,(type),(nr),0) #define _IOR(type,nr,size)    _IOC(_IOC_RE ...

  6. (十)Linux内核中的常用宏container_of

    Container_of在Linux内核中是一个常用的宏,用于从包含在某个结构中的指针获得结构本身的指针,通俗地讲就是通过结构体变量中某个成员的首地址进而获得整个结构体变量的首地址. Containe ...

  7. Linux内核中的常用宏container_of

    Container_of在Linux内核中是一个常用的宏,用于从包含在某个结构中的指针获得结构本身的指针,通俗地讲就是通过结构体变量中某个成员的首地址进而获得整个结构体变量的首地址. Containe ...

  8. Linux内核中的常用宏container_of其实很简单【转】

    转自:http://blog.csdn.net/npy_lp/article/details/7010752 开发平台:Ubuntu11.04 编 译器:gcc version 4.5.2 (Ubun ...

  9. 嵌入式C语言自我修养 01:Linux 内核中的GNU C语言语法扩展

    1.1 Linux 内核驱动中的奇怪语法 大家在看一些 GNU 开源软件,或者阅读 Linux 内核.驱动源码时会发现,在 Linux 内核源码中,有大量的 C 程序看起来“怪怪的”.说它是C语言吧, ...

随机推荐

  1. NSIS安装程序制作工具判断系统是否安装.NET

    前段时间忙了很久的系统总算上线了,由于是WinForm程序不能整个文件夹的发给客户使用.所以必须要打包,记得以前在VS2005中是自带部署功能的.现在换了VS2013那个部署功能完全弄不清方向.最后在 ...

  2. nrm 的使用

    我们介绍过cnpmjs.org和淘宝 npm 两个 NPM 镜像.除此之外,还有一些国外的 NPM 镜像.不同地区访问不同的镜像速度可能有差异,因此有时候需要切换 NPM 镜像.相比每次切换时都手动指 ...

  3. 0058 Spring MVC如何向视图传值--Model--ModelMap--ModelAndView--@ModelAttribute

    MVC,模型.视图.控制器,请求来了,控制器负责找到Controller进行一通计算,计算的结果放到模型里,再找视图把结果呈现出来. 请求里一般都包含了一些参数,前面说了,Spring MVC有很多种 ...

  4. wp中的动画

    动画目标:必须是依赖属性.可以用于Double,Color,Point,Object类型.对应的动画类后面加Animation,下面代码演示旋转360°. <Button Content=&qu ...

  5. 【高可用HA】Apache (2) —— Mac下安装多个Apache Tomcat实例

    Mac 下安装多个Apache Tomcat实例 tomcat版本:tomcat-8.0.29 参考来源: Installing Tomcat 7.0.x on OS X 在mac系统安装Apache ...

  6. kafka_zookeeper_配置文件配置

    server.properties配置如下: broker.id=0 num.network.threads=2 num.io.threads=8 socket.send.buffer.bytes=1 ...

  7. yii的一些方法的解析和blog的详细解析

    1.  存取数据库方法存储第一种(SAVE )存表时候用到  例子: $post=new Post;$post->title='sample post';$post->content='c ...

  8. Mac下面的SecureCRT(附破解方案) 更新到最新的7.2的破解方案

    继续更新到7.2的破解.只是升级了下secureCRT到7.2,方法还是不变 相信很多人升级到了7.2的SecureCRT之后原来的破解方案失效了,一直也有人问新的破解方案,发现了,不敢独享放上crt ...

  9. 快速理解 Phoenix : SQL on HBASE

    转自:http://blog.csdn.net/colorant/article/details/8645081 ==是什么 == 目标Scope EasyStandard SQL access on ...

  10. android 虚拟键盘控制

    软键盘显示的原理 软键盘的本质是什么?软键盘其实是一个Dialog! InputMethodService为我们的输入法创建了一个Dialog,并且将该Dialog的Window的某些参数(如Grav ...