Chinaunix首页 | 论坛 | 博客
  • 博客访问: 6563292
  • 博文数量: 159
  • 博客积分: 10424
  • 博客等级: 少将
  • 技术积分: 14594
  • 用 户 组: 普通用户
  • 注册时间: 2010-07-14 12:45
个人简介

啦啦啦~~~

文章分类
文章存档

2015年(5)

2014年(1)

2013年(5)

2012年(10)

2011年(116)

2010年(22)

分类: LINUX

2011-12-24 16:34:47

作者:gfree.wind@gmail.com
博客:blog.focus-linux.net   linuxfocus.blog.chinaunix.net
 
 
本文的copyleft归gfree.wind@gmail.com所有,使用GPL发布,可以自由拷贝,转载。但转载请保持文档的完整性,注明原作者及原链接,严禁用于任何商业用途。
======================================================================================================
虽然不是内核工程师,但是也经常使用这两个宏,不过一直没有深究。刚才看了Bean_lee评论了一篇关于likely()和unlikely()的文章,于是也过去凑了个热闹。

该文章前面没有什么问题,我也不再重复,但是最后有个错误。“另外有一点要注意的是,由于likely定义时用的常量是1,unlikely用的常量是0,这正好符合c/c++语言中bool变量的实际值,而_builtin_expect()函数对exp与c进行严格相等的比较的,
因此使用likely和unlikely时,其参数应该只使用逻辑表达式,因为逻辑表达式的值只有0或1。除非真要判断某个变量的值是1或0时,才会将其它类型的参数传给likely或unlikely。这一点可能很多人会不小心用错。”,引自:http://blog.chinaunix.net/space.php?uid=24708340&do=blog&id=3047035

我看到这段文字时,吓了一跳。我使用likely和unlikely时从来没注意过参数非得是逻辑表达式的值啊,即0和1。难道都用错了。。。想了一下,就知道该博主想错了。

当使用likely和unlikely的时候,参数可以为任何表达式。不是逻辑表达式没有关系,绝不会有错。我来解释一下:
  1. #define likely(x) __builtin_expect(!!(x),1)
  2. #define unlikely(x) __builtin_expect(!!(x),0)
这是likely和unlikely的定义。看一眼定义,!!(x)这个用法就会让人觉得奇怪,为什么要!!呢?否定的否定,不就是肯定吗?干嘛多此一举呢?这就是一个技巧,学习kernel的时候,可以学到不少类似的技巧。

按照__builtin_expect的定义,要用第一个参数和第二个参数比较,它期望的值是true。第二个值是1。这里的!!(x)就是为了保证当x本身作为逻辑值为true的时候,其!!(x)值为1。举个简单的例子:
  1. if (likely(5)) {
  2.     printf("Hit!\n");
  3. }
  4. else {
  5.     printf("Not hit\n");
  6. }
本身if (5)为true,因为C标准里面规定任何非0的值均为true。Ok,!(5)为0,而!!(5)为1。这就是为啥likely和unlikely要使用!!(x),就为了其逻辑判断的值为1或者0。

关于为什么likely和unlikely可以提高程序的performance,我就不献丑了。给个官方的文献链接:http://kernelnewbies.org/FAQ/LikelyUnlikely

总的来说,它们是对编译器的一种指示,告诉编译器哪个分支更有可能发生,来最大的满足CPU的流水线作业。

阅读(4460) | 评论(2) | 转发(8) |
给主人留下些什么吧!~~

GFree_Wind2011-12-24 18:58:44

Bean_lee: 你说的这个情况 ,我以前也纳闷过,不过我发文章前弄明白了。博主的确是弄错了。
likely和unlikely,是告诉编译器,判断条件是true的概率大还是还是false的概率.....
我是被那篇文章中的那段话给吓着了。。。以为真的是这样呢。

我后来本想再写一篇,likely的优化原理的。但是linux已经说得很清楚了,我就不重复了。就像你说的,无非是告诉编译器哪个分支概率更大,给编译器一个分支预测的一个提示。

Bean_lee2011-12-24 18:02:15

你说的这个情况 ,我以前也纳闷过,不过我发文章前弄明白了。博主的确是弄错了。
likely和unlikely,是告诉编译器,判断条件是true的概率大还是还是false的概率大,从而引导编译器,生成机器友好的汇编指令。likely那个宏的含义是条件成立的可能性非常大,请优先走这个分支。

评论热议
请登录后评论。

登录 注册