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

    文章

    10990

    浏览量

    206734
  • 编译器
    +关注

    关注

    1

    文章

    1577

    浏览量

    48614
收藏 人收藏

    评论

    相关推荐

    C语言中likelyunlikely的使用

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

    linux kernel

    linux kernel 有什么学习技巧吗?
    发表于 06-11 18:23

    LinuxKernel的运行原理概述

    和软件之间提供了一个层,严格地从计算机科学的角度讲,Linux中所指的Kernel是Linus Torvalds90年代初期写的那些代码。
    发表于 07-24 07:45

    说说android与linux有啥区别

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

    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'>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 5610次阅读
    U-boot传递RAM和<b class='flag-5'>Linux</b> <b class='flag-5'>kernel</b>读取RAM参数的解析

    你知道linux kernel内存碎片防治技术?

    Linux kernel组织管理物理内存的方式是buddy system(伙伴系统),而物理内存碎片正式buddy system的弱点之一,为了预防以及解决碎片问题,kernel采取了一些实用技术,这里将对这些技术进行总结归纳。
    发表于 05-10 10:59 822次阅读

    Linux Kernel 5.2.2震撼发布!

    在首个维护版本更新之后,在kernel.org官网上已经将Linux Kernel 5.2分支标记为“Stable”,意味着已经准备好大规模部署了,所有GNU/Linux发行版本都应该
    的头像 发表于 08-09 17:01 2689次阅读

    Linux Kernel 5.6-rc7候选版本发布

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

    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年。华为是第一个在 Linux
    的头像 发表于 05-24 13:52 2122次阅读

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

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