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. 受用一生的高效 PyCharm 使用技巧(一)
  2. 会声会影X4 初学者速成 转
  3. 转发:听老罗讲这一代人的学习方法有感
  4. ubuntu 两块硬盘挂载不上_win10 轉 Ubuntu
  5. 工作374-前端margin:0 auto为什么会失效
  6. ssm配置文件引用细节
  7. 要是面试官再问我synchronized,我就这么答
  8. RHadoop(一)
  9. Java编写ASCII码转换
  10. 智能随访系统:提升患者综合服务能力和就医体验,提高医院品牌价值与服务质量
  11. 计算机输入什么指令关机,电脑关机命令是什么 电脑关机命令详解
  12. Fortigate(飞塔)防火墙密码恢复
  13. GSM/GPRS之一-GSM基础知识
  14. 2021年钟霖高考成绩查询,2021年高考倒计时祝福短信
  15. 软考高项你想要的全在这
  16. 使用Google colab的GPU运行resnet
  17. 计算机网络汇聚层,【大白电气】接入层、汇聚层、核心层——中大型计算机网络系统结构介绍及交换机选型建议...
  18. 金庸笔下用脚发暗器_移动的艺术:使用明暗器图创建动画材质
  19. 解决我无限网络只能上QQ不能上网的问题!!
  20. 【码上实战】【立体匹配系列】经典AD-Census: (6)多步骤视差优化

热门文章

  1. 【在线专家问答】 - QA专家 张志会 与您分享QA实战经验
  2. [图文]历届奥斯卡影后(中)
  3. HE学业水平考试游记 By cellur925
  4. android realm 简书,Realm简介
  5. Is the server running on host localhost (::1) and accepting         TCP/IP connections on port 5
  6. echarts 显示暂无数据的具体方法
  7. Oracle数据库迁移-EMC迁移到华为6800
  8. X2-xml基础知识二[xml]
  9. Matlab数组A中删除数组B的元素
  10. 戴尔poweredge r730服务器配置以及系统安装