= 2.96) 的內(nèi)建函數(shù),提供給程序員使用的,目的是將"分支轉(zhuǎn)移"的信息提供給編譯器,這" />
0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

likely與unlikely在Linux kernel的區(qū)別

麥辣雞腿堡 ? 來(lái)源:嵌入式Linux系統(tǒng)開(kāi)發(fā) ? 作者:嵌入式Linux系統(tǒng)開(kāi) ? 2023-07-20 11:06 ? 次閱讀

likely() 與 unlikely() 在 Linux kernel 中隨處可見(jiàn),那為什么要用它們?它們之間有什么區(qū)別呢?

首先明確:

if (likely(value)) 等價(jià)于 if (value)
if (unlikely(value)) 等價(jià)于 if (value)

也就是說(shuō) likely() 和 unlikely() 從閱讀和理解的角度是一樣的。

這兩個(gè)宏在內(nèi)核中定義如下:

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

這里的 __builtin_expect() 函數(shù)是 gcc(version >= 2.96) 的內(nèi)建函數(shù),提供給程序員使用的,目的是將"分支轉(zhuǎn)移"的信息提供給編譯器,這樣編譯器對(duì)代碼進(jìn)行優(yōu)化,以減少指令跳轉(zhuǎn)帶來(lái)的性能下降。

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

也就是說(shuō),使用 likely(),執(zhí)行 if 后面的語(yǔ)句的機(jī)會(huì)更大,使用 unlikely(),執(zhí)行 else 后面的語(yǔ)句機(jī)會(huì)更大一些。

通過(guò)這種方式,編譯器在編譯過(guò)程中,會(huì)將可能性更大的代碼緊跟著后面的代碼,從而減少指令跳轉(zhuǎn)帶來(lái)的性能上的下降。

這樣 cache 在預(yù)取數(shù)據(jù)時(shí)可以盡量取到真正要跑的數(shù)據(jù),增加了 cache 的命中率。

不用對(duì) likely 和 unlikely 感到迷惑,須要知曉的就是 if(likely(a>b)) 和 if(a>b) 在功能上是等價(jià)的。示例代碼:

#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;
}

這樣的寫(xiě)法,編譯器在對(duì)代碼進(jìn)行優(yōu)化時(shí),就會(huì)知道第一個(gè) if 判斷后,很可能跑的是 else 語(yǔ)句,cpu 就會(huì)先對(duì) else 進(jìn)行取址。

總之,likely 和 unlikely 的功能就是增加 cache 的命中率,提高系統(tǒng)執(zhí)行速度。

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11329

    瀏覽量

    209975
  • 編譯器
    +關(guān)注

    關(guān)注

    1

    文章

    1640

    瀏覽量

    49200
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    Linux kernel內(nèi)存管理模塊結(jié)構(gòu)分析

    基于上面章節(jié)的需求,Linux kernel從虛擬內(nèi)存(VM)、DMA mapping以及DMA buffer sharing三個(gè)角度,對(duì)內(nèi)存進(jìn)行管理.
    發(fā)表于 09-19 11:55 ?1800次閱讀
    <b class='flag-5'>Linux</b> <b class='flag-5'>kernel</b>內(nèi)存管理模塊結(jié)構(gòu)分析

    C語(yǔ)言中likelyunlikely的使用

    單片機(jī)/嵌入式編程中,對(duì)速度要求比較高,likelyunlikely就是一個(gè)比較好的技巧,適用于有if-else分支,且知道哪個(gè)發(fā)生概率大的情況。
    發(fā)表于 07-21 14:53 ?1236次閱讀

    說(shuō)說(shuō)android與linux有啥區(qū)別

    目錄區(qū)別與聯(lián)系嵌入式系統(tǒng)物聯(lián)網(wǎng)行業(yè)中的應(yīng)用物聯(lián)網(wǎng)嵌入式系統(tǒng)的特征區(qū)別與聯(lián)系這個(gè)問(wèn)題很多人問(wèn),尤其是初入嵌入式的菜鳥(niǎo)。其實(shí)大家都認(rèn)為android是java,已經(jīng)不是linux,殊不知
    發(fā)表于 11-04 07:53

    Linux Kernel核心中文手冊(cè)

    Linux Kernel核心中文手冊(cè):Hardware Basic( 硬件基礎(chǔ)知識(shí)) 一個(gè)操作系統(tǒng)必須和作為它的基礎(chǔ)的硬件系統(tǒng)緊密配合。操作系統(tǒng)需要使用一些只有硬件才能提供的功能。為了完整的了解 Linux
    發(fā)表于 12-08 10:15 ?39次下載
    <b class='flag-5'>Linux</b> <b class='flag-5'>Kernel</b>核心中文手冊(cè)

    Developing Linux kernel space

    This thesis introduces how to develop kernel level device drivers on Linux platform in detail.
    發(fā)表于 08-21 10:22 ?10次下載

    linux內(nèi)核kernel-api

    linux內(nèi)核kernel-api,不知道從哪兒找的了,但是你如果想要做內(nèi)核編程,這是一部api函數(shù)詳盡的工具書(shū)?。。∥逍峭扑]
    發(fā)表于 10-30 17:16 ?19次下載

    Linuxkernel_timer教程

    Linuxkernel_timer教程,很好的Linux自學(xué)資料,快來(lái)學(xué)習(xí)吧。
    發(fā)表于 04-15 17:59 ?12次下載

    Linux運(yùn)行期間升級(jí)Linux系 統(tǒng)Uboot+kernel+Rootfs

    Linux運(yùn)行期間升級(jí)Linux系 統(tǒng)Uboot+kernel+Rootfs
    發(fā)表于 10-30 08:43 ?5次下載
    <b class='flag-5'>在</b><b class='flag-5'>Linux</b>運(yùn)行期間升級(jí)<b class='flag-5'>Linux</b>系 統(tǒng)Uboot+<b class='flag-5'>kernel</b>+Rootfs

    Linux-kernel-3 0的移植記錄

    Linux-kernel-3 0的移植記錄
    發(fā)表于 10-31 11:33 ?7次下載
    <b class='flag-5'>Linux-kernel</b>-3 0的移植記錄

    Linux Kernel 5.2.2震撼發(fā)布!

    首個(gè)維護(hù)版本更新之后,kernel.org官網(wǎng)上已經(jīng)將Linux Kernel 5.2分支標(biāo)記為“Stable”,意味著已經(jīng)準(zhǔn)備好大規(guī)模
    的頭像 發(fā)表于 08-09 17:01 ?2888次閱讀

    Linux Kernel 5.6-rc7候選版本發(fā)布

    新冠病毒爆發(fā)期間,Linus Torvalds 宣布了 Linux 5.6 的第七個(gè)每周候選版本,即 Linux Kernel 5.6-rc7 的發(fā)布。
    的頭像 發(fā)表于 03-26 15:52 ?5536次閱讀

    Linux_Kernel_Developments內(nèi)核開(kāi)發(fā)

    Linux_Kernel_Developments內(nèi)核開(kāi)發(fā)詳細(xì)說(shuō)明。
    發(fā)表于 04-07 14:27 ?37次下載
    <b class='flag-5'>Linux_Kernel</b>_Developments內(nèi)核開(kāi)發(fā)

    Linux Kernel5.10維護(hù)周期將從2年延長(zhǎng)至6年

    經(jīng)過(guò) Linux Kernel 社區(qū)成員的共同努力,Linux Kernel 5.10 維護(hù)周期最終確定從2年延長(zhǎng)至6年。華為是第一個(gè)
    的頭像 發(fā)表于 05-24 13:52 ?2376次閱讀

    嵌入式linux系統(tǒng)和嵌入式android系統(tǒng)的區(qū)別和聯(lián)系

    目錄區(qū)別與聯(lián)系嵌入式系統(tǒng)物聯(lián)網(wǎng)行業(yè)中的應(yīng)用物聯(lián)網(wǎng)嵌入式系統(tǒng)的特征區(qū)別與聯(lián)系這個(gè)問(wèn)題很多人問(wèn),尤其是初入嵌入式的菜鳥(niǎo)。其實(shí)大家都認(rèn)為android是java,已經(jīng)不是linux,殊不知
    發(fā)表于 11-01 17:05 ?5次下載
    嵌入式<b class='flag-5'>linux</b>系統(tǒng)和嵌入式android系統(tǒng)的<b class='flag-5'>區(qū)別</b>和聯(lián)系

    Linux kernel的kretprobe機(jī)制和kprobe有何區(qū)別?

    Linux kernel 的 kretprobe 機(jī)制和 kprobe 完全不同,本質(zhì)原因在于,函數(shù)的入口地址是固定的,但函數(shù)的返回地址不固定,由于返回位置不固定,無(wú)法固定函數(shù)大小,無(wú)法事先插樁。
    的頭像 發(fā)表于 08-07 09:15 ?1154次閱讀
    <b class='flag-5'>Linux</b> <b class='flag-5'>kernel</b>的kretprobe機(jī)制和kprobe有何<b class='flag-5'>區(qū)別</b>?