Linux 中多处出现 likely 和 unlikely 的使用,它们的定义如下:

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

函数原型

__builtin_expect 是 GCC 提供的内置函数 (built-in functions),函数原型是

long __builtin_expect (long exp, long c)

函数的返回值是 exp,它告诉编译器, 代码期望的是 exp == c 。

注意:代码中!!,并不是特殊符号,只是两次取反,通过这种技巧,可以将任意量转换为0或1。0 为 0,非 0 值为1。

使用该函数的作用

现代处理器的工作远超前于当前指令,比如从内存读新指令,译码指令等。只要指令遵循的是简单的顺序,那么这种指令流水线化就能很好的工作。当遇到分支的时候,处理器必须猜测分支该往哪个方向走,如果猜测错误,就会损失处理器的性能,因此需要分支预测技术。
__builtin_expect 就是用来为处理器的分支预测提供信息,帮助处理器进行分支预测。

if (unlikely(x)) {do_something();
}
return x;

编译器会让主分支是概率最大的分支,尽量减少程序跳转的情况。以上代码会被编译器调整为如下的汇编逻辑。

if(x)goto L1;return x;
L1:do_something();return x;

通过汇编代码查看编译器实际动作

int normal_fun(int x)
{if (x) {do_something();}return x;
}int unlikely_fun(int x)
{if(__builtin_expect(x, 0)) {do_something();}return x;
}int likely_fun(int x)
{if(__builtin_expect(x, 1)) {do_something();}return x;
}

汇编代码如下:

normal_fun:pushq   %rbxmovl    %edi, %ebxtestl   %edi, %edijne     .L4       ;normal 版本采用默认的分支预测
.L2:movl    %ebx, %eaxpopq    %rbxret
.L4:movl    $0, %eaxcall    do_somethingjmp     .L2
unlikely_fun:           pushq   %rbxmovl    %edi, %ebxtestl   %edi, %edijne     .L8     ;使等于1的情况作为跳转分支。
.L6:movl    %ebx, %eaxpopq    %rbxret
.L8:movl    $0, %eaxcall    do_somethingjmp     .L6
likely_fun:pushq   %rbxmovl    %edi, %ebxtestl   %edi, %edije      .L10 ;使等于1的情况作为主分支。movl    $0, %eaxcall    do_something
.L10:movl    %ebx, %eaxpopq    %rbxret

参考:
Other Built-in Functions Provided by GCC
How do the likely/unlikely macros in the Linux kernel work and what is their benefit?
GCC __builtin_expect 解析

解析Linux中的 likely 和 unlikely相关推荐

  1. 解析linux中的vfs文件系统机制,解析Linux中的VFS文件系统机制

    解析Linux中的VFS文件系统机制 本文阐述 Linux 中的文件系统部分,源代码来自基于 IA32 的 2.4.20 内核.总体上说Linux下的文件系统主要可分为三大块:一是上层的文件系统的系统 ...

  2. ☀️苏州程序大白解析Linux 中的虚拟网络接口☀️《❤️记得收藏❤️》

    ☀️苏州程序大白解析Linux 中的虚拟网络接口☀️<❤️记得收藏❤️> 目录

  3. Linux内核中的vfs,解析 Linux 中的 VFS 文件系统机制

    在Linux系统中,每个分区都是一个文件系统,都有自己的目录层次结构.Linux的最重要特征之一就是支持多种文件系统,这样它更加灵 活,并可以和许多其它种操作系统共存.由于系统已将Linux文件系统的 ...

  4. 解析 Linux 中的 VFS 文件系统机制

    简介: 本文阐述 Linux 中的文件系统部分,源代码来自基于 IA32 的 2.4.20 内核.总体上说 Linux 下的文件系统主要可分为三大块:一是上层的文件系统的系统调用,二是虚拟文件系统 V ...

  5. 解析Linux中的系统安全及应用(二)

    各位小伙伴大家好,本次和大家分享的是Linux系统中的系统安全及应用的相关理论知识及操作.我将通过以下几点和相关的实验进行分析说明:(接上篇) 五.使用su命令切换用户: 1.用途及方法 用途:Sub ...

  6. 解析 Linux 中的 VFS 文件系统机制(1)

    住:这里只转载一篇,还有几篇没有转载,但这里给出源地址: http://www.51cto.com/art/200803/67283.htm 摘要:本文阐述 Linux 中的文件系统部分,源代码来自基 ...

  7. 深入解析Linux中的fork函数

    1.定义 #include <unistd.h> #include<sys/types.h> pid_t fork( void ); pid_t 是一个宏定义,其实质是int, ...

  8. linux之getcwd函数解析,Linux 中C语言getcwd()函数的用法

    Linux 中C语言getcwd()函数的用法 先来看该函数的声明: #include char *getcwd(char *buf,size_t size); 介绍: 参数说明:getcwd()会将 ...

  9. 解析Linux中的VFS文件系统机制

    文阐述 Linux 中的文件系统部分,源代码来自基于 IA32 的 2.4.20 内核.总体上说Linux下的文件系统主要可分为三大块:一是上层的文件系统的系统调用,二是虚拟文件系统 VFS(Virt ...

最新文章

  1. BZOJ 1047 理想的正方形(单调队列)
  2. 记一次关于SSM框架的使用错误
  3. Activemq 安全机制以及稳定性研究
  4. BZOJ 3240([Noi2013]矩阵游戏-费马小定理【矩阵推论】-%*s-快速读入)
  5. dac0832产生梯形波程序C语言,在8086系统中用DAC0832输出一个三角波,一个梯形波,和一个正弦波。...
  6. 程序员怎么面试求职?需要注意哪些因素?
  7. 20145237第六周学习总结
  8. css动画定义,CSS3中Animation动画的定义和调用
  9. 蓝桥杯 ADV-208 算法提高 矩阵相乘
  10. 【PostgreSQL-9.6.3】临时表
  11. php俄语包,俄语资源汇总 - 俄语 | Russian | Pусский - 声同小语种论坛 - Powered by phpwind...
  12. Whisper的应用
  13. ffi一些常见的错误
  14. LeetCode——自除数
  15. java c HTML,javac html标签
  16. HTML+CSS简单漫画网页设计成品--(红猪(9页)带注释)
  17. 2进制 16进制 计算机术语,十六进制转二进制计算器
  18. 三菱FX5U传送指令
  19. 我的数字IC学习路线
  20. 记 计算机 科学学院 教师,永做学生的操作系统——记计算机科学技术学院、软件学院教师金虎...

热门文章

  1. “离开360时,它只给了我一块钱”
  2. 阿里云服务器域名解析教程 ?
  3. Linux 设置开机启动项的几种方法
  4. 高压MOS管1000V/2A 可代替IXFP4N100 数据表(PDF)
  5. 如何在Windows中使用“ shutdown r”命令重新启动和关闭计算机?
  6. 设计分享|单片机抢答器(汇编)
  7. realm教程 android,Realm for Android基本教程
  8. 【每日一练】20—CSS实现文字动画效果
  9. 哈尔滨市中省直单位医疗保险制度细则出台
  10. 最受美国创业团队欢迎​的10个常用商业工具