0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

likely与unlikely在Linux kernel的区别

麦辣鸡腿堡 来源:嵌入式Linux系统开发 作者:嵌入式Linux系统开 2023-07-20 11:06 次阅读

likely() 与 unlikely() 在 Linux kernel 中随处可见,那为什么要用它们?它们之间有什么区别呢?

首先明确:

if (likely(value)) 等价于 if (value)
if (unlikely(value)) 等价于 if (value)

也就是说 likely() 和 unlikely() 从阅读和理解的角度是一样的。

这两个宏在内核中定义如下:

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

这里的 __builtin_expect() 函数是 gcc(version >= 2.96) 的内建函数,提供给程序员使用的,目的是将"分支转移"的信息提供给编译器,这样编译器对代码进行优化,以减少指令跳转带来的性能下降。

__builtin_expect(!!(x), 1)表示 x 的值为真的可能性更大.
__builtin_expect(!!(x), 0)表示 x 的值为假的可能性更大.

也就是说,使用 likely(),执行 if 后面的语句的机会更大,使用 unlikely(),执行 else 后面的语句机会更大一些。

通过这种方式,编译器在编译过程中,会将可能性更大的代码紧跟着后面的代码,从而减少指令跳转带来的性能上的下降。

这样 cache 在预取数据时可以尽量取到真正要跑的数据,增加了 cache 的命中率。

不用对 likely 和 unlikely 感到迷惑,须要知晓的就是 if(likely(a>b)) 和 if(a>b) 在功能上是等价的。示例代码:

#include xxx
#define unlikely(x) __builtin_exp ect(!!(x), 0)
#define likely(x) __builtin_exp ect(!!(x), 1)
int main()
{
   int a=2,b=4;
   
   if(unlikely(a<=b)){
       printf("in the unlikely,is not your expecting!n");
   } else {
       printf("in the unlikely, is your exp ectingn");
   }
   
   if(likely(a<=b)){
       printf("in the likely, is your exp ectingn");
   }
  return 0;
}

这样的写法,编译器在对代码进行优化时,就会知道第一个 if 判断后,很可能跑的是 else 语句,cpu 就会先对 else 进行取址。

总之,likely 和 unlikely 的功能就是增加 cache 的命中率,提高系统执行速度。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Linux
    +关注

    关注

    87

    文章

    11221

    浏览量

    208883
  • 编译器
    +关注

    关注

    1

    文章

    1618

    浏览量

    49043
收藏 人收藏

    评论

    相关推荐

    Linux kernel内存管理模块结构分析

    基于上面章节的需求,Linux kernel从虚拟内存(VM)、DMA mapping以及DMA buffer sharing三个角度,对内存进行管理.
    发表于 09-19 11:55 1744次阅读
    <b class='flag-5'>Linux</b> <b class='flag-5'>kernel</b>内存管理模块结构分析

    C语言中likelyunlikely的使用

    单片机/嵌入式编程中,对速度要求比较高,likelyunlikely就是一个比较好的技巧,适用于有if-else分支,且知道哪个发生概率大的情况。
    发表于 07-21 14:53 1172次阅读

    说说android与linux有啥区别

    目录区别与联系嵌入式系统物联网行业中的应用物联网嵌入式系统的特征区别与联系这个问题很多人问,尤其是初入嵌入式的菜鸟。其实大家都认为android是java,已经不是linux,殊不知
    发表于 11-04 07:53

    Linux Kernel核心中文手册

    Linux Kernel核心中文手册:Hardware Basic( 硬件基础知识) 一个操作系统必须和作为它的基础的硬件系统紧密配合。操作系统需要使用一些只有硬件才能提供的功能。为了完整的了解 Linux
    发表于 12-08 10:15 39次下载
    <b class='flag-5'>Linux</b> <b class='flag-5'>Kernel</b>核心中文手册

    Developing Linux kernel space

    This thesis introduces how to develop kernel level device drivers on Linux platform in detail.
    发表于 08-21 10:22 10次下载

    linux内核kernel-api

    linux内核kernel-api,不知道从哪儿找的了,但是你如果想要做内核编程,这是一部api函数详尽的工具书!!!五星推荐
    发表于 10-30 17:16 19次下载

    Linuxkernel_timer教程

    Linuxkernel_timer教程,很好的Linux自学资料,快来学习吧。
    发表于 04-15 17:59 12次下载

    Linux运行期间升级Linux系 统Uboot+kernel+Rootfs

    Linux运行期间升级Linux系 统Uboot+kernel+Rootfs
    发表于 10-30 08:43 5次下载
    <b class='flag-5'>在</b><b class='flag-5'>Linux</b>运行期间升级<b class='flag-5'>Linux</b>系 统Uboot+<b class='flag-5'>kernel</b>+Rootfs

    Linux-kernel-3 0的移植记录

    Linux-kernel-3 0的移植记录
    发表于 10-31 11:33 7次下载
    <b class='flag-5'>Linux-kernel</b>-3 0的移植记录

    U-boot传递RAM和Linux kernel读取RAM参数的解析

    U-boot会给Linux Kernel传递很多参数,如:串口,RAM,videofb等。而Linux kernel也会读取和处理这些参数。两者之间通过struct tag来传递参数。
    的头像 发表于 02-06 08:24 5824次阅读
    U-boot传递RAM和<b class='flag-5'>Linux</b> <b class='flag-5'>kernel</b>读取RAM参数的解析

    Linux Kernel 5.2.2震撼发布!

    首个维护版本更新之后,kernel.org官网上已经将Linux Kernel 5.2分支标记为“Stable”,意味着已经准备好大规模
    的头像 发表于 08-09 17:01 2851次阅读

    Linux Kernel 5.6-rc7候选版本发布

    新冠病毒爆发期间,Linus Torvalds 宣布了 Linux 5.6 的第七个每周候选版本,即 Linux Kernel 5.6-rc7 的发布。
    的头像 发表于 03-26 15:52 5476次阅读

    Linux_Kernel_Developments内核开发

    Linux_Kernel_Developments内核开发详细说明。
    发表于 04-07 14:27 37次下载
    <b class='flag-5'>Linux_Kernel</b>_Developments内核开发

    Linux Kernel5.10维护周期将从2年延长至6年

    经过 Linux Kernel 社区成员的共同努力,Linux Kernel 5.10 维护周期最终确定从2年延长至6年。华为是第一个
    的头像 发表于 05-24 13:52 2325次阅读

    Linux kernel的kretprobe机制和kprobe有何区别

    Linux kernel 的 kretprobe 机制和 kprobe 完全不同,本质原因在于,函数的入口地址是固定的,但函数的返回地址不固定,由于返回位置不固定,无法固定函数大小,无法事先插桩。
    的头像 发表于 08-07 09:15 991次阅读
    <b class='flag-5'>Linux</b> <b class='flag-5'>kernel</b>的kretprobe机制和kprobe有何<b class='flag-5'>区别</b>?