在Linux kernel的源代码中,经常能见到if(likely(x))或if(unlikely(x))之类的用法,其确切含义需要说明一下,以便更好的理解kernel的源代码。
likely与unlikely这两个宏在linux/compiler.h中的定义如下:
#define likely(x)   __builtin_expect(!!(x),1)
#define unlikely(x)   __builtin_expect(!!(x),0)
很明显,需要先弄清楚这个__builtin_expect()函数的意义。
__builtin_expect()是gcc的一个内建函数,其原型如下:
long __builtin_expect (long exp, long c);
记住该函数由GCC本身提供,用于优化代码。只中参数exp为任一表达式,c必须为常量值,其意义是在exp==c时,该函数返回非0值,意即希望exp==c。
回到likely和unlikely,likely实际是希望表达式x==1,即表达式x成立,并且在代码实际执行中,表达式x在绝大多数情况下是成立的,相反,unlikely是希望表达式在绝大多数情况下不成立,
如果有下列代码:
if(unlikely(a > b) {
    foo();
}
这段代码的意思是,在绝大多数情况下a > b这个表达式是不成立的,不成立时执行函数foo().
另外有一点要注意的是,由于likely定义时用的常量是1,unlikely用的常量是0,这正好符合c/c++语言中bool变量的实际值,而_builtin_expect()函数对exp与c进行严格相等的比较的,
因此使用likely和unlikely时,其参数应该只使用逻辑表达式,因为逻辑表达式的值只有0或1。除非真要判断某个变量的值是1或0时,才会将其它类型的参数传给likely或unlikely。这一点可能很多人会不小心用错。
使用这两个宏定义的好处是优化条件判断

关于Linux Kernel中的宏定义likely和unlikely相关推荐

  1. Linux 内核中的宏定义

    Linux 内核中的宏定义 rtoax 日期 内核版本:linux-5.10.13 注释版代码:https://github.com/Rtoax/linux-5.10.13 __attribute__ ...

  2. 如何在Linux kernel Makefile中添加宏定义

    如何在Linux kernel Makefile中添加宏定义: CFLAGS_object.o += -DMACRO_NAME 在编译object.o时定义宏MACRO_NAME,在kernel中添加 ...

  3. Linux kernel中常见的宏整理

    0x00 宏的基本知识 // object-like #define 宏名 替换列表 换行符 //function-like #define 宏名 ([标识符列表]) 替换列表 换行符 替换列表和标识 ...

  4. Linux内核源码中使用宏定义的若干技巧

    在C中,宏定义的概念虽然简单,但是真要用好却并不那么容易,下面从Linux源码中抽取一些宏定义的使用方法,希望能从中得到点启发: 1. 类型检查 比如module_init的宏定义: 点击(此处)折叠 ...

  5. Linux内核中max()宏的奥妙何在?(一)

    Linux内核中max()宏的奥妙何在?(一) 1.max()宏那点事 在Linux内核中,有这样四个比较大小的函数,如下: max(x,y) //两个数求最大值 min(x,y) //两个数求最小值 ...

  6. Linux kernel 中模块化的平台驱动代码介绍

    介绍 在linux kernel中通过module_platform_driver来实现模块化平台驱动.大量的设备驱动程序都基于该种方式来实现,使用频次非常的高,在linux kernel 5.4.1 ...

  7. 内存访问顺序 - part2: 屏障及Linux kernel中屏障的使用

    文章目录 屏障是什么 Linux Kernel 中的屏障 Linux 屏障 API 一般的屏障 强制性屏障 SMP 条件屏障 隐式屏障 其他屏障 屏障的开销 未来的文章 本文翻译自 Memory ac ...

  8. Linux内核中max()宏的奥妙何在?(二)——大神Linus对这个宏怎么看?

    最新max()宏 上回,我们在<Linux内核中max()宏的奥妙何在?(一)>一文中说到,在3.18.34版Linux内核源码中的max()宏,采用了GCC的扩展特性,可以避免一些错误. ...

  9. linux kernel中的栈的介绍

    目录 1.linux kernel中的中断irq的栈stack (1).arm32体系的irq的栈 (2).arm64体系的irq的栈 2.linux kernel中的栈stack (1).概念介绍: ...

最新文章

  1. 运行python-thrift的DEMO
  2. Java面向对象特征介绍
  3. Word Embedding News|词嵌入新鲜事:六月刊:GPT-3来了
  4. Spring--@within和@target的区别
  5. Demuxed:编解码器和压缩的未来
  6. “没有找到iliertutil.dll,因此这个应用程序未能启动。”文件拷贝 PE 或者 dos...
  7. SmartRaiden 和 Lighting Network 进行去中心化跨链原子资产交换
  8. 工作211:新的封装组件 秒呀
  9. 某IDC科技风登录页面模板
  10. sketch文件导出没有背景色怎么办? sketch背景色消失的解决办法
  11. EasyUI datagrid增加统计当前页中某列的最大值,最小值,平均值,总和
  12. Atitit.常见的异常分类 目录 1. 双元分类法 1 1.1. 按照语言分 java js c# php等 1 1.2. 通用常见异常vs 特定异常 1 1.3. Runtime ex vs c
  13. 2018款macbook pro如何安装windows双系统
  14. MLX90614修改地址
  15. python编写安装脚本_ido-Python 安装脚本包
  16. 在职读研拓宽视野,社科院与杜兰大学合办金融管理硕士项目为你提供能量
  17. 三层交换 VLAN 互访配置
  18. xshell连接不上虚拟机Linux
  19. 抗肿瘤靶向药物丨小分子化合物 or 单克隆抗体?- MedChemExpress
  20. 数据库作业 1:绘制crow‘s foot图

热门文章

  1. pandas 排序一个变量
  2. priority_queue
  3. php编译减少大小,C++_减小VC6编译生成的exe文件的大小的方法,1、减小VC6编译生成的exe文件的 - phpStudy...
  4. android 之ListView分页效果以及从网络上加载数据一系列的综合运用
  5. 初识广播机制(监听网络状态的改变,监听网络是否可以使用)
  6. 使用隐式Intent打开系统内置拨号界面
  7. android 获取其他布局,android listview onItemClick中获取其他item的布局
  8. 4che3 scu发送超时设置_Redis实现订阅发布与批量发送短信
  9. python super 变参数问题(五)
  10. keras 提取某一层的feature_map