看内核时总遇到if(likely( )){}或是if(unlikely( ))这样的语句,最初不解其意,现在有所了解,所以也想介绍一下。

likely() 与 unlikely()是内核(我看的是2.6.22.6版本,2.6的版本应该都有)中定义的两个宏。位于/include/linux/compiler.h中,
具体定义如下:
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)

__builtin_expect是gcc(版本>=2.96,网上写的,我没验证过)中提供的一个预处理命令(这个名词也是网上写的,我想叫函数更好些),有利于代码优化。gcc(version 4.4.0)具体定义如下:
long __builtin_expect (long exp, long c) [Built-in Function]

注解为:
You may use __builtin_expect to provide the compiler with branch prediction information. In general, you should prefer to use actual profile feedback for this (‘-fprofile-arcs’), as programmers are notoriously bad at predicting how their programs actually perform. However, there are applications in which this data is hard to collect.The return value is the value of exp, which should be an integral expression. The semantics of the built-in are that it is expected that exp == c.

它的意思是:我们可以使用这个函数人为告诉编绎器一些分支预测信息“exp==c” 是“很可能发生的”。

#define likely(x) __builtin_expect(!!(x), 1)也就是说明x==1是“经常发生的”或是“很可能发生的”。
使用likely ,执行if后面语句的可能性大些,编译器将if{}是的内容编译到前面, 使用unlikely ,执行else后面语句的可能性大些,编译器将else{}里的内容编译到前面。这样有利于cpu预取,提高预取指令的正确率,因而可提高效率。

举个例子(内核版本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互换或不用都不会影响程序的正确性。但可能会影响程序的效率。

if(likely(foo))  //认为foo通常为1

if(unlikely(foo)) //认为foo通常为0

感谢各位光顾!
不知道有没有写清楚,望指正!
疑惑:
为什么likely或是unlikely要定义成__builtin_expect(!!(x), 1),而不直接用__builtin_expect(x, 1)?" !!(x) "与" x "有什么不同?

另外内核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

linux中的likely和unlikely相关推荐

  1. c++ 进程快照_如何在 Linux 中找出内存消耗最大的进程

    很多次,你可能遇见过系统消耗了过多的内存.如果是这种情况,那么最好的办法是识别出 Linux 机器上消耗过多内存的进程. -- Magesh Maruthamuthu(作者) 很多次,你可能遇见过系统 ...

  2. linux的tar中ztvf,linux中的tar命令(2)

    实例4:只将 /tar 内的 部分文件解压出来 命令: tar -zxvf /opt/soft/test/log30.tar.gz log2013.log 输出: [root@localhost te ...

  3. centos6.5 php5.2,Linux中PHP安装与配置(CentOS-6.5:php-5.2.13)

    1 PHP简介     PHP(PHP: Hypertext Preprocessor的缩写,中文名:"超文本预处理器")是一种通用开源脚本语言.语法吸收了C语言.Java和Per ...

  4. java 外部类似_[求指点] 如何用java 实现类似linux中管道调用外部程序的功能

    想写个小程序实现类似linux中管道的功能,创建一个外部子进程,然后主进程不断地写输入给子进程,而后把子进程的返回值取出. 如下的小代码就是从stdin读入一个字符串,调用子进程(cat)返回这个串, ...

  5. linux 修改java版本_Linux 有问必答:如何在 Linux 中改变默认的 Java 版本

    提问:当我尝试在Linux中运行一个Java程序时,我遇到了一个错误.看上去像程序编译所使用的Java版本与我本地的不同.我该如何在Linux上切换默认的Java版本? 当Java程序编译时,编译环境 ...

  6. linux ls 命令 路径,使用ls命令在Linux中使用完整路径列出文件

    许多人会发现,这是重复的问题,但我已经经历了所有问题,然后问及这个主题,但没有为我工作.使用ls命令在Linux中使用完整路径列出文件 我想打印使用ls命令的特定文件格式的完整路径名到目前为止,我发现 ...

  7. linux中的ln属性,linux 常用基础命令 ln 详细介绍

    命令介绍: ln是linux中又一个非常重要命令,ln是为某一个文件在另外一个位置建立一个同步的链接.当我们需要在不同的目录,用到相同的文件时,我们不需要在每一个需要的目录下都放一个必须相同的文件,我 ...

  8. linux内核定义的常用信号6,Linux中的信号

    在 Linux 中,理解信号的概念是非常重要的.这是因为,信号被用于通过 Linux 命令行所做的一些常见活动中.例如,每当你按 Ctrl+C 组合键来从命令行终结一个命令的执行,你就使用了信号.每当 ...

  9. linux用户空间 限制吗,在Linux中限制用户空间

    在Linux中限制用户的磁盘使用空间使用的是Quota,一般Quota在安装Linux时就已包括在内核中,不需要另行安装.Quota可以从两方面指定磁盘的储存限制: 使用者所能够支配的索引节点(ino ...

  10. Linux中的粘滞位

    Linux中的粘滞位 Sticky 位是一个访问权限标志位,可以用来标示文件和路径. 历史: 粘滞位是在1974年Unix的第5版中引入的,用来设置可执行文件.当可执行文件设置粘滞位之后,它能够指示操 ...

最新文章

  1. GAN还有这种操作!谷歌大脑和X实验室利用模拟条件和域适应提高机器抓取效率(附论文)
  2. vue的slot作用域插槽使用案例
  3. vue监听对象某一个属性
  4. 程序员如何更好地获取用户信息?
  5. 2017 年全球十大突破技术:逼格很高很难懂
  6. win7下用UtralISO制作U盘系统盘--UltraISO打开Ubuntu只有EFI文件夹
  7. 树以及树简单的遍历方法
  8. c235delc杂合变异遗传吗_血常规正常就真的没有地贫吗?
  9. 2022阿里笔试分享(2022.3.25)
  10. android层叠view,ViewPager层叠卡片效果
  11. 北京地铁各条线路介绍
  12. Docker Hub镜像构建错误:returned a non-zero code: 8
  13. 技术干货:Linux Shell 编程基础,看这一篇就够了!
  14. div点击穿透,CSS属性pointer-events :none;实现护眼模式, 夜间模式遮罩
  15. Android 5.x浏览器webView或者qqX5崩溃,Resources$NotFoundException:String resource ID #0x2040003
  16. Spring之Specification复杂查询和Criteria查询
  17. 痞子衡职场经验与感悟分享 - 索引
  18. 盘点世上最牛的5篇博士论文,跪拜!
  19. [NOI2008]假面舞会
  20. JAVA如何自定义布局单选框,5分钟DIY一个自定义单选框单选按钮

热门文章

  1. 2017年11月学习心得报告
  2. listary让你工作效率,快的起飞的软件!程序猿标配
  3. 程序员数学(26)–反比例函数
  4. B2C网站的网络营销策略
  5. 创业型的公司,请不要给员工开空头支票。要来,就来点实际的!
  6. 开发方向-后端-java-并发编程
  7. 多节点CDN缓存加速系统wdcdn2.2版本发布(20111115)
  8. 经典剪枝算法的例题——Sticks详细注释版
  9. Win10突然卡死的原因调查
  10. 终极对决?360报QQ声明为木马