Chinaunix首页 | 论坛 | 博客
  • 博客访问: 249517
  • 博文数量: 88
  • 博客积分: 1429
  • 博客等级:
  • 技术积分: 523
  • 用 户 组: 普通用户
  • 注册时间: 2010-01-18 15:31
文章分类

全部博文(88)

文章存档

2017年(2)

2016年(24)

2013年(1)

2012年(24)

2011年(15)

2010年(22)

我的朋友

分类:

2012-01-06 14:21:42

作者: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,我就不献丑了。给个官方的文献链接:

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

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