likely和unlikely函数

今天看源码的时候遇到likely和unlikely两个函数,第一感觉是很困惑,1、都是在if的判断语句中,2、其中参数也都是简单的比大小等类型的判断语句,3、感觉没有likely和unlikely也可以判断,那么为啥非要加上一个“函数”呢?

于是上网查明这个likely和unlikely

快速了解:
likely和unlikely分别表明了要判断的条件很有可能会发生和不会发生。
再直白一点,
如果我们觉得一个if里的条件很大概率是真,那么我们使用likely,反之使用unlikely。

深入一点点:

likely() 与 unlikely()是内核中定义的两个宏。位于/include/linux/compiler.h中,
具体定义如下:
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
!!(x)有助于将x的结果变为bool,在这里与x的区别并不大(会默认转换类型)。但用于返回值的时候体现出较大的却别。如 return !!(x),这里就将原来的x的类型转换成了bool型。第二个参数1,0表示!!(x)的值的很可能为1或0。

系统编译后在汇编级的代码会有少许区别,主要会改变if语句执行的跳转(if判断为错时需要跳到下一条语句),使用__builtin_expect可以使汇编代码结构更合理,使得每次判断很大概率为真,减少了跳转。仅当小概率的事件发生时才跳转,这样减少了部分跳转语句。

同时,结合操作系统知识,我们知道计算机执行时cpu的计算速度非常快,往往要预加载一些数据(利用缓存实现,缓存读取速度很快,但成本高,一般较小),提前准备好数据,来提高cpu效率,当我们遇到一些需要判断的情况时,比如遇到if语句,由于是预加载我们只有执行了if语句才知道加载的对不对,所以可能会出现预加载的数据不对,如果加载数据不对那么就要重新加载这个过程相对cpu来说是非常耗时的。

由于cpu计算速度非常快,预加载数据是必须的,增大预加载数据的命中率是非常必要的,操作系统通常会自动优化,来提高命中率。然而系统自带的优化并不是万能的,此时我们需要给系统提供信息,改善优化,增加命中率。

likely和unlikely函数相关推荐

  1. 数据库中自定义排序规则,Mysql中自定义字段排序规则,Oracle中自定义字段排序规则,decode函数的用法,field函数的用法

    数据库中自定义排序 场景:有一张banner表,表中有一个status字段,有0, 1, 2三个状态位,我想要 1,0,2的自定义排序(这里是重点),然后再进行之上对sequence字段进行二次排序( ...

  2. Mysql函数group_concat、find_in_set 多值分隔字符字段进行数据库字段值翻译

    Mysql函数group_concat.find_in_set进行数据库字段值翻译 场景 配方表:记录包含的原料 sources表示原料,字段值之间用逗号分隔 原料表:对应原料id和原料名称 现需要查 ...

  3. C++ 笔记(34)— C++ exit 函数

    当遇到 main 函数中的 return 语句时,C++ 程序将停止执行.但其他函数结束时,程序并不会停止.程序的控制将返回到函数调用之后的位置.然而,有时候会出现一些非常少见的情况,使得程序有必要在 ...

  4. C++ 笔记(30)— 友元函数与友元类

    我们知道类的私有成员只能在类的成员函数内部访问,如果想在别处访问对象的私有成员,只能通过类提供的接口(成员函数)间接地进行.这固然能够带来数据隐藏的好处,利于将来程序的扩充,但也会增加程序书写的麻烦. ...

  5. 浅显易懂 Makefile 入门 (07)— 其它函数(foreach 、if、call、origin )

    1. foreach 函数 foreach 函数定义如下: $(foreach <var>,<list>,<text>) 函数的功能是:把参数 <list&g ...

  6. 浅显易懂 Makefile 入门 (06)— 文件名操作函数(dir、notdir、suffix、basename、addsuffix、addperfix、join、wildcard)

    编写 Makefile 的时候,很多情况下需要对文件名进行操作.例如获取文件的路径,去除文件的路径,取出文件前缀或后缀等等. 注意:下面的每个函数的参数字符串都会被当作或是一个系列的文件名来看待. 1 ...

  7. Go 学习笔记(65)— Go 中函数参数是传值还是传引用

    Go 语言中,函数参数传递采用是值传递的方式.所谓"值传递",就是将实际参数在内存中的表示逐位拷贝到形式参数中.对于像整型.数组.结构体这类类型,它们的内存表示就是它们自身的数据内 ...

  8. Go 学习笔记(61)— Go 高阶函数、函数作为一等公民(函数作为输入参数、返回值、变量)的写法

    函数在 Go 语言中属于"一等公民(First-Class Citizen)"拥有"一等公民"待遇的语法元素可以如下使用 可以存储在变量中: 可以作为参数传递给 ...

  9. C++ 笔记(26)— 主函数 main(int argc, char *argv[]) 参数说明

    带形参的 main 函数,如 int main( int argc, char* argv[], char **env ) 是 UNIX .Linux 以及 Mac OS 操作系统中 C/C++ 的 ...

  10. OpenCV 笔记(09)— 常用的数据结构和函数(Vec、Point、Scalar、Size、Rect、cvtColor)

    1. Vec 对象类型 Vec 是一个主要用于数值向量的模板类.我们可以定义向量的类型和组件的数量: Vec<double, 19> myVector 我们还可以使用任何的预定义类型: t ...

最新文章

  1. JSR349(Bean Validation 1.1)
  2. Python模块EasyGui专题学习
  3. 关于有限自动机的一篇不错的文章
  4. Python Revisited Day 07 (文件处理)
  5. 香港一小巴侧翻致1死16伤 警方:未见机件故障
  6. 移动通信蜂窝原理例题整理
  7. iperf 测试局域网速度
  8. 家乡的楼房正在往高层发展
  9. eslint不报错 vue_2-2【微信小程序全栈开发课程】index页面搭建--ESlint格式错误
  10. Android 成用户隐私安全问题严重
  11. houdini帮助文档_edge wrangle在houdini的vex优化与应用
  12. gamma分布 pytorch_pytorch之添加BN的实现
  13. 阶段3 1.Mybatis_09.Mybatis的多表操作_5 完成user的一对多查询操作
  14. 简述angularjsh中constant和$filter的用法
  15. linux中文变成日文,linux nkf 日文编码转换命令[转载]
  16. RTL8762DW手环烧录方法
  17. 球半篮球比分,西篮甲:沙萨基 VS 华伦西亚 5月31日
  18. 百度地图API权限部分
  19. 各种奇奇怪的不明链接!长期更...
  20. “高精尖”智慧钢厂轻松打造!图扑软件数字孪生yyds

热门文章

  1. Java 高效压缩zip
  2. CTex的搬运工(初学者)
  3. Postgresql-1-解决报错:connection to localhost:5432 refused that the postmaster is accepting TCP/IP
  4. windows下用批处理文件修改网络适配器设置
  5. linux下运行yolo,Linux下 安装YOLO
  6. DayuCMS 1.525 /include/global.func.php Foreground Arbitrary Code Execution
  7. 数据分析项目-英国礼品商城数据分析
  8. docker(11、Docker Swarm4)11、副本数量(replicated 和 global )12、Label 控制 Service 的位置 13、如何配置 Health Check
  9. 在ubuntu 搭建TFTP服务器时的步骤及 出现的常见错误:Restarting tftpd-hpa (via systemctl): tftpd-hpa.serviceJob for tftpd-
  10. 2022安全员-C证操作证考试题及模拟考试