参考文档:
https://www.cnblogs.com/cdwodm/p/4448773.html
https://blog.csdn.net/npy_lp/article/details/7175517
Linux内核设计与实现

gcc内建了一条指令用于优化,在一个条件经常出现,或者该条件很少出现的时候,编译器可以根据这条指令对条件分支选择进行优化。内核把这条指令封装成了宏,比如likely()和unlikely() ,宏定义如下:

/* linux-2.6.38.8/include/linux/compiler.h */
# define likely(x)  __builtin_expect(!!(x), 1)
# define unlikely(x)    __builtin_expect(!!(x), 0)

在Linux内核中可以经常看到以下类似的代码块:

if (unlikely(error)) {/*...*/
}
else {/*...*/
}
if (likely(success)) {/*...*/
}
else {/*...*/
}

在代码块中,在if条件判断语句中使用unlikely()函数表示写这个程序的人认为error的值在大部分情况下都为假(0),gcc编译器识别到unlikely()函数后,会将条件判断为假执行的代码块(也就是else中的代码)放到紧跟前面的程序位置。换句话说,else下的代码放在了if下的代码的前面,因为if条件判断中大部分情况为假嘛,所以把条件为假的代码块放在前面,可以在大部分情况下先执行else下的代码,以提高程序运行的效率,达到优化性能的目的。
同样的,在if条件判断语句中使用likely()函数表示写这个程序的人认为success的值在大部分情况下都为真(1),gcc编译器识别到likely函数后,会将条件看判断为真的代码块(也就是if中的代码)放到紧跟前面的程序位置。同理可以达到优化性能的目的。

那么,搞清楚likely()和unlikely()函数的作用后,__builtin_expect函数是什么?
__builtin_expect函数是GCC编译器内置的函数,用于对条件选择语句进行优化。函数原型如下:

long  __builtin_expect (long exp, long c)
  • exp是一个表达式
  • c是期望值,必须为常量
  • 返回值是exp的值,它应该是一个整数表达式。内置的语义是期望 exp == c,就是说希望exp的值跟c的值一样,因为编译器将以c的值作为条件所执行的代码块优化到前面(紧跟前一条程序代码)。

用一个程序来测试__builtin_expect 函数的作用:

#include <stdio.h>int main(void)
{int a;for(a=0;a<5;a++){if(__builtin_expect(a, 4))printf("if: a = %d,builtin_expect=%d\n", a, __builtin_expect(a, 4));elseprintf("else: a = %d,builtin_expect=%d\n", a, __builtin_expect(a, 4));}return 0;
}

结果为:

可以看到只有当a==0时,才执行else中的代码,其余情况全部执行的是if中的代码。也就说明__builtin_expect函数返回值是exp表达式的值。
结合likely()和unlikely()的宏定义来看,likely(value)中value的值只有为真时会加快代码的执行效率(条件为真所执行的代码块放在最前面的,会最先执行),value的值为假,就会先跳过为真的代码,执行条件为假的代码,这多了一个程序跳转的步骤。同理,对于unlikely()函数是一样的道理。所以,exp == c条件成立的机会占绝大多数,那么性能将会得到提升,否则性能反而会下降。
因此,程序员对于value的值的预估必须要准确,如果判断正确,确实是这个条件占压倒性的地位,那么性能会得到提升;如果你搞错了,性能反而会下降。

likelly()和unlikely()详解相关推荐

  1. 从命令行到IDE,版本管理工具Git详解(远程仓库创建+命令行讲解+IDEA集成使用)

    首先,Git已经并不只是GitHub,而是所有基于Git的平台,只要在你的电脑上面下载了Git,你就可以通过Git去管理"基于Git的平台"上的代码,常用的平台有GitHub.Gi ...

  2. JVM年轻代,老年代,永久代详解​​​​​​​

    秉承不重复造轮子的原则,查看印象笔记分享连接↓↓↓↓ 传送门:JVM年轻代,老年代,永久代详解 速读摘要 最近被问到了这个问题,解释的不是很清晰,有一些概念略微模糊,在此进行整理和记录,分享给大家.在 ...

  3. docker常用命令详解

    docker常用命令详解 本文只记录docker命令在大部分情境下的使用,如果想了解每一个选项的细节,请参考官方文档,这里只作为自己以后的备忘记录下来. 根据自己的理解,总的来说分为以下几种: Doc ...

  4. 通俗易懂word2vec详解词嵌入-深度学习

    https://blog.csdn.net/just_so_so_fnc/article/details/103304995 skip-gram 原理没看完 https://blog.csdn.net ...

  5. 深度学习优化函数详解(5)-- Nesterov accelerated gradient (NAG) 优化算法

    深度学习优化函数详解系列目录 深度学习优化函数详解(0)– 线性回归问题 深度学习优化函数详解(1)– Gradient Descent 梯度下降法 深度学习优化函数详解(2)– SGD 随机梯度下降 ...

  6. CUDA之nvidia-smi命令详解---gpu

    nvidia-smi是用来查看GPU使用情况的.我常用这个命令判断哪几块GPU空闲,但是最近的GPU使用状态让我很困惑,于是把nvidia-smi命令显示的GPU使用表中各个内容的具体含义解释一下. ...

  7. Bert代码详解(一)重点详细

    这是bert的pytorch版本(与tensorflow一样的,这个更简单些,这个看懂了,tf也能看懂),地址:https://github.com/huggingface/pytorch-pretr ...

  8. CRF(条件随机场)与Viterbi(维特比)算法原理详解

    摘自:https://mp.weixin.qq.com/s/GXbFxlExDtjtQe-OPwfokA https://www.cnblogs.com/zhibei/p/9391014.html C ...

  9. pytorch nn.LSTM()参数详解

    输入数据格式: input(seq_len, batch, input_size) h0(num_layers * num_directions, batch, hidden_size) c0(num ...

最新文章

  1. Microbiome:应用多维宏组学方法协同揭示复杂细菌群落对目标底物代谢的菌间相互关系(一作解读)...
  2. python怎么画形状_python – matplotlib – 如何绘制随机导向的矩形(或任何形状)?...
  3. P2152 [SDOI2009]SuperGCD
  4. 我三年开发经验,从字节跳动抖音离职后,看看这篇文章吧!
  5. 读取html文件,让其中的内容和notepad打开这个html的样子一样。
  6. VS2010 书签 工具的使用方法
  7. 免费snmp oid下载
  8. Unity3d 通过协程来实现文件的全部加载后执行
  9. bili弹幕姬_B站弹幕姬插件——弹幕日志
  10. ShowModalDialog数据缓存的清除方法
  11. 用 reStructuredText 写作:快速入门指南
  12. 制作u盘linux课程报告,定制U盘Linux系统总结报告-Linux文档类资源
  13. mysql导致的502_ab压测过程中出现502及操作数据库失败
  14. android隐藏其他应用图标,【Android】隐藏app图标以及隐式启动其他APP
  15. Android app打开手机应用市场上对应的应用
  16. 基于SSM实现医院预约挂号系统
  17. loT行业生死竞速:Aqara绿米得用户得天下
  18. [iOS]分享文件到QQ好友或微信好友
  19. JVM源码分析之Attach机制实现完全解读
  20. 如何给电脑系统重置系统?方法其实很简单

热门文章

  1. 百度谷歌大收录 达到500页 非常感谢!
  2. (十四)Alian 的 Spring Cloud 订单服务调用自动生成的API
  3. SDNU_ACM_ICPC_2020_Winter_Practice_4th(补题2020.2.2)
  4. Unity:代码自动生成脚本
  5. WAF---Web应用防火墙 功能梳理
  6. 这个岗位国内人才缺口超30万?突破职场瓶颈,薪资飙升?
  7. python疲劳驾驶困倦低头检测
  8. 三层交换机配置及命令
  9. clickhouse: Cannot execute replicated DDL query on leader
  10. 浅谈脱壳中的附加数据问题(overlay)