在内核中常会见到下面这样的代码。

bvl = bvec_alloc(gfp_mask, nr_iovecs, &idx);
if (unlikely(!bvl)) {  mempool_free(bio, bio_pool);
  bio = NULL;
  goto out;
}
 

这个likely()和unlikely()其实是宏定义。原始定义在 include/linux/compiler.h中,如下:

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

__builtin_expect是GCC内建的函数。下面引用linuxform中的一篇讲GCC扩展文章

的一部分(原我找到的也是引用的文章,此处给出链接),里面解释得很清楚。

——————————————————- * __builtin_expect(EXP, C)  内建函数 __builtin_expect 用于为编译器提供分支预测信息,其返回值是整数表达式 EXP
的值,C 的值必须是编译时常数。例如: ++++ include/linux/compiler.h 13: #define likely(x) __builtin_expect((x),1) 14: #define unlikely(x) __builtin_expect((x),0) ++++ kernel/sched.c 564: if (unlikely(in_interrupt())) { 565: printk(”Scheduling in interruptn”); 566: BUG(); 567: }  这个内建函数的语义是 EXP 的预期值是 C,编译器可以根据这个信息适当地重排 语句块的顺序,使程序在预期的情况下有更高的执行效率。上面的例子表示处于中 断上下文是很少发生的,第 565-566 行的目标码可能会放在较远的位置,以保证 经常执行的目标码更紧凑。 ——————————————————-

总结,这个宏主要是优化的作用。如果英文好的话可以看文章一开始给出的

在kernelnewbies中的链接,那里有更详细的解说。


细心的人应该留意到有一点不同,likely()一开始偶给的定义为__builtin_expect(!!(x),1)。


后来的文章解说中成了__builtin_expect((x),1)。


这应该是后来的版本更改所至。就是新近版本的内核已经更改成__builtin_expect(!!(x),1).


加上个“!!”有什么好处哩。我想是因为使代码强壮与兼容的原因。因为不能保证x表达式的结果一定是1或0,有可能是非0数。加了“!!”,结果就一定是在1和0范围内了。

LikelyUnlikely相关推荐

  1. 【ELL】ell学习之__builtin_expect(likely-unlikely)

    一.前述 在很多源码如Linux内核.Glib等,我们都能看到likely()和unlikely()这两个宏,通常这两个宏定义是下面这样的形式. // __builtin_expect()函数是GCC ...

  2. 几个常用的宏:likely和unlikely __raw_writel

    在源码中,宏likely和unlikely 是这么定义的(位于include/linux/compiler.h): #define likely(x) __builtin_expect(!!(x), ...

  3. 我也说说宏定义likely()和unlikely()

    作者:gfree.wind@gmail.com 博客:blog.focus-linux.net   linuxfocus.blog.chinaunix.net    本文的copyleft归gfree ...

  4. __builtin_expect详解

    在GTK+2.0源码中有很多这样的宏:G_LIKELY和G_UNLIKELY.比如下面这段代码: if (G_LIKELY (acat == 1)) /* allocate through magaz ...

  5. I/O函数 writel __raw_writel mb()/rmb()/wmb()

    在邮件列表里讨论了一下writel是如何实现的,这个函数实现在操作系统层,有内存保护的情况下,往一个寄存器或者内存地址写一个数据. 在arch/alpha/kernel/io.c中有 188 void ...

  6. 分支预测优化之__builtin_expect

    1.引言 在很多源码如Linux内核.Glib等,我们都能看到likely()和unlikely()这两个宏,通常这两个宏定义是下面这样的形式. #define likely(x) __builtin ...

  7. java race condition_java 多线程下race condition问题

    这个问题的讨论来自内部的一个关于"多线程环境下使用Hashmap的安全问题"的讨论,HashMap多线程的问题之前已经提过一次,见之前的blog.本篇文章主要讨论多线程下race ...

  8. likely(x)与unlikely(x)函数,即__builtin_expect的使用

    目录 1.引言 2. 函数声明 2.1. 功能描述 2.2. 参数详解 ① exp  ② c 2.3. 返回值 2.4. 使用方法 3. RATIONALE(原理) 4. likely()和unlik ...

最新文章

  1. 【Python金融量化 7- 100 】、七、计算两只股票方差和相关性
  2. 【2017.11.29 周三 转载之李航博士的文章:大数据分析到底需要多少种工具?】...
  3. Win7双开3389
  4. 【限时免费】LiveVideoStack Meet | 北京:卷时代,多媒体人 生存指北
  5. 初步体验数据驱动之美---TreeView
  6. [css] css的linear-gradient有什么作用呢?
  7. 科学计算机fx-82es,fx-82ES PLUS A -2卡西欧计算器-计算器 函数科学-卡西欧官方商城...
  8. 他走了,留下了3800亿元的帝国
  9. 我要学ASP.NET MVC 3.0(十三): MVC 3.0 防止跨站点请求伪造 (CSRF) 攻击
  10. win11资源管理器历史搜索记录如何删除 Windows11禁用资源管理器历史搜索记录的设置方法
  11. 创建表 备注 修改表结构 修改约束
  12. private访问权限java_Java 访问权限控制:public、private、protected
  13. 在VScode中使用opencv,配置好了以后无法找到opencv2/opencv.hpp的问题
  14. png图片背景转换成透明
  15. 9008刷机教程oppo_OPPO手机解锁教程
  16. ant design pro中click事件传参正确写法(获取事件对象e)
  17. Python 高效提取 HTML 文本的方法
  18. 万能险生存金什么意思,一文告诉你!
  19. IDEA 报错:Information:java: Errors occurred while compiling module ‘项目名‘
  20. 开除AI伦理学家,谷歌如何从“不作恶”到“不宽容”?

热门文章

  1. linux如何卸载已安装软件,linux中如何卸载已安装的软件-linux运维
  2. 设置Xshell最大显示行数
  3. nn.GLU()的实现
  4. rust主播排行_「Rust日报」2019每周精选 • 第四期
  5. (Python)使用Gdal+Scipy获得Dem的经纬度的高程值(双线性和三次样条内插)
  6. 2022年度技术总结
  7. gpu灵魂拷问各路神仙
  8. 坚果云 + Typora实现云同步
  9. Permissions 0664 for ‘yanyongx.pem‘ are too open.
  10. 网络私有制行得通吗?