likely()与unlikely()函数的意义_jasonLee_lijiaqi的博客-程序员秘密

技术标签: likely  unlikely  内存分配研究  linux  操作系统  linux内核  

看内核时总遇到if(likely( )){}或是if(unlikely( ))这样的语句,最初不解其意,现在有所了解,所以也想介绍一下。

likely() 与 unlikely()是内核中定义的两个宏。位于/include/linux/compiler.h中,
具体定义如下:

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

__builtin_expect是gcc(版本>=2.96,网上写的,我没验证过)中提供的一个预处理命令(这个名词也是网上写的,我想叫函数更好些),有利于代码优化。gcc(version 4.4.0)具体定义如下:
long __builtin_expect (long exp, long c) [Built-in Function]

注解为:
You may use __builtin_expect to provide the compiler with branch prediction information. In general, you should prefer to use actual profile feedback for this (‘-fprofile-arcs’), as programmers are notoriously bad at predicting how their programs actually perform. However, there are applications in which this data is hard to collect.The return value is the value of exp, which should be an integral expression. The semantics of the built-in are that it is expected that exp == c.

它的意思是:我们可以使用这个函数人为告诉编绎器一些分支预测信息“exp==c” 是“很可能发生的”。

#define likely(x) __builtin_expect(!!(x), 1)也就是说明x==1是“经常发生的”或是“很可能发生的”。

使用likely ,执行if后面语句的可能性大些,编译器将if{}是的内容编译到前面, 使用unlikely ,执行else后面语句的可能性大些,编译器将else{}里的内容编译到前面。这样有利于cpu预取,提高预取指令的正确率,因而可提高效率。

举个例子(内核版本2.6.22.6):/kernel/shed.c中有一段:

if (likely(!active_balance)) {
/* We were unbalanced, so reset the balancing interval */
sd->balance_interval = sd->min_interval;
} else {
/*
* If we've begun active balancing, start to back off. This
* case may not be covered by the all_pinned logic if there
* is only 1 task on the busy runqueue (because we don't call
* move_tasks).
*/
if (sd->balance_interval max_interval)
sd->balance_interval *= 2;
}

编译过程中,会将if后面{}里的内容编译到前面,else 后面{}里的内容编译到后面。若将likely换成unlikely 则正好相反。

总之,likely与unlikely互换或不用都不会影响程序的正确性。但可能会影响程序的效率。

if(likely(foo)) //认为foo通常为1

if(unlikely(foo)) //认为foo通常为0

另外内核2.6.31.5中likely和unlikely还有一种定义:

# ifndef likely
# define likely(x) (__builtin_constant_p(x) ? !!(x) : __branch_check__(x, 1))
# endif

# ifndef unlikely
# define unlikely(x) (__builtin_constant_p(x) ? !!(x) : __branch_check__(x, 0))
# endif
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/jasonLee_lijiaqi/article/details/79864056

智能推荐

java编译和运行命令_使用CMD命令编译和运行Java程序_古不帅的纸盒子的博客-程序员秘密

对于初学者来说,使用CMD命令(Unix以及类Unix系统采用Termial)来编译和运行Java的好处是让初学者直观地体会到编译(Compile)这一步骤,加深记忆。所谓编译就是将文本文件xxx.java翻译为Java虚拟机可以识别的字节码文件xxx.class,这部分原理暂且不做深究,直接介绍如何使用CMD命令执行Java程序。Unix/Linux或者Mac iOS等其它类Unix系统,方法都...

《Flask Web开发:基于Python的Web应用开发实战》学习笔记(一)_python flask web开发实战_强大的石头的博客-程序员秘密

转载于:http://pdf.us/2017/10/03/451.html,感谢这位大神《Flask Web开发:基于Python的Web应用开发实战》学习笔记这里是第一部分的学习笔记。第一部分:Flask简介准备工作Gitgit clone https://github.com/miguelgrinberg/flasky.gitgit checkout 1

服务器虚拟化超融合选型-VMware_weixin_33737774的博客-程序员秘密

企业在服务器虚拟化选择上面,往往会选择一款性价比高,稳定可靠的平台。并且该平台是先进的,开放的,不会被某一个厂商所绑定。因此我们将针对稳定可靠、平台先进性、开放性进评估,最终从性价比的角度考虑选择。稳定可靠 VMware公司1998年成立,vSphere作为VMware公司最核心的产品,已经经历大小二十几个版本,目前最新的版本是vSphere...

redis高可用之主从架构_Edingbrugh.南空的博客-程序员秘密

当主从库的连接恢复之后,从库首先会给主库发送 psync 命令,并把自己当前的 slave_repl_offset 发给主库,主库会判断自己的 master_repl_offset 和 slave_repl_offset 之间的差距。此外,传输 RDB 文件也会占用主库的网络带宽,同样会给主库的资源使用带来压力。那么,一旦主从库完成了全量复制,它们之间就会一直维护一个网络连接,主库会通过这个连接将后续陆续收到的命令操作再同步给从库,这个过程也称为基于长连接的命令传播,可以避免频繁建立连接的开销。

VMware ESXi 8.0U1a macOS Unlocker & OEM BIOS (标准版和厂商定制版)_sysin.org的博客-程序员秘密

VMware ESXi 8.0 Update 1a macOS Unlocker & OEM BIOS (标准版和厂商定制版)

Direct3D提高篇:HLSL编程实现PhotoShop滤镜效果 - 黑白化_weixin_34067102的博客-程序员秘密

RenderMonkey图像处理的架子-图像黑白化下面我们通过一个简单的例子,先来完成一个最简单的图像处理-把图像黑白化。来说明RenderMonkey如何来处理数字图像。Render Monkey和VC类似,内置了一些工程代码。在这里我们在RenderMonkey的工作区菜单里选择Add Effect -> DirectX->Screen-AlignedQuad. 在生成的工...

随便推点

视锥剔除优化_ue5视锥剔除_xoyojank的博客-程序员秘密

1. 基本相交测试. 只需要测试包围盒的两个角(这个几乎所有人都做了)2. 平面连续测试. 根据上次测试的结果来优化用于测试的平面顺序3. 八分体测试. 对于对称的视锥体可以减少一半的测试4. 父子测试. 对于有父子关系的包围盒, 父在内则子在内, 父在外则子在外, 父相交则需要递归测试5. 变换连续测试. 根据移动和旋转的方向来优化测试. 如上一帧在外的处于移动方向的相反方向的话, 这帧肯定也在外面.6. 雷达测试(Gems5). 适用于包围体为球形的情况.

kaggle数据科学从业者分析报告_kaggle数据分析报告_二郎银的博客-程序员秘密

数据科学从业者调查分析数据描述2017年8月26日,全球最大的数据科学社群Kaggle发布了数据科学/机器学习业界现状全行业调查的数据集。调查问卷数据从2017年8月7日~8月25日收集。受访者囊括了来自50多个国家的16716+位从业者,根据kaggle的调查问卷数据集,我们挖掘一些有营养的信息。变量选择一共 228个变量,我们选择部分感兴趣的问题分析, 变量说明表如下:...

Loongson Kernel编译与使用_zhanghongjuan0的博客-程序员秘密

龙芯处理器使用的是开源Linux操作系统,同时结合龙芯处理器的特点进行了移植优化。Kernel源码的编译采用的是交叉编译方式,研发中心目前进行bios与kernel开发的服务器是www.loongson.cn/dev/。目前龙芯kernel全部基于git进行管理,下载kernel前需要熟悉一下git版本管理工具的使用,常用命令为git-clone、git-diff、git-status、git

Power收集_青烟绕指柔!的博客-程序员秘密

题目链接:Power收集显然可以dp。然后比如当前为第x行第y列,那么可以从第x-1行,纵坐标为:[y-t,y+t]当中的最大值转移。显然后面可以单调队列维护。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>//#define int long longusing namespace std;const int N=4e3+10;int n,m,k,t,q[N],

node-cache_weixin_33980459的博客-程序员秘密

From: https://www.npmjs.com/package/node-cache Simple and fast NodeJS internal caching.A simple caching module that has set, get and delete methods and works a little bit like memcached. Keys ca...

推荐文章

热门文章

相关标签