欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++關(guān)鍵字之likely和unlikely詳解

 更新時(shí)間:2022年10月15日 11:50:13   作者:misaka-mikoto  
這篇文章主要介紹了C++關(guān)鍵字之likely和unlikely,C++20之前的,likely和unlikely只不過(guò)是一對(duì)自定義的宏,而C++20中正式將likely和unlikely確定為屬性關(guān)鍵字,本文給大家詳細(xì)講解,需要的朋友可以參考下

什么是likely和unlikely

既然程序是我們程序員所寫(xiě),在一些明確的場(chǎng)景下,我們應(yīng)該比CPU和編譯器更了解哪個(gè)分支條件更有可能被滿足。我們是否可將這一先驗(yàn)知識(shí)告知編譯器和CPU, 提高分支預(yù)測(cè)的準(zhǔn)確率,從而減少CPU流水線分支預(yù)測(cè)錯(cuò)誤帶來(lái)的性能損失呢?答案是可以!它便是likely和unlikely。在Linux內(nèi)核代碼中,這兩個(gè)宏的應(yīng)用比比皆是。下面是他們的定義:

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

likely,用于修飾if/else if分支,表示該分支的條件更有可能被滿足。而unlikely與之相反
以下為示例。unlikely修飾argc > 0分支,表示該分支不太可能被滿足。

#include <cstdio>

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

int main(int argc, char *argv[])
{
    if (unlikely(argc > 0)) {
        puts ("Positive\n");
    } else
    {
        puts ("Zero or Negative\n");
    }
    return 0;
}

likely/unlikely的原理

接下來(lái),我們從匯編指令分析likely/unlikely到底是如何起作用的?
首先我們將上述代碼中的unlikely去掉,然后反匯編,作為對(duì)照組
匯編如下,我們看到,if分支中的指令被編譯器放置于分支跳轉(zhuǎn)指令jle相鄰的位置,即CPU流水線在遇到j(luò)le指令所代表的的'岔路口'時(shí),更傾向于走if分支

.LC0:
        .string "Positive\n"
.LC1:
        .string "Zero or Negative\n"
main:
        sub     rsp, 8
        test    edi, edi                
        jle     .L2                     ; 如果argc <= 0, 跳轉(zhuǎn)到L2
        mov     edi, OFFSET FLAT:.LC0   ; 如果argc > 0, 從這里執(zhí)行
        call    puts
.L3:
        xor     eax, eax
        add     rsp, 8
        ret
.L2:
        mov     edi, OFFSET FLAT:.LC1
        call    puts
        jmp     .L3

接著我們?cè)趇f分支中加上unlikely, 反匯編如下。這里的情況正好與對(duì)照組相反,if分支下的指令被編譯器放置于遠(yuǎn)離跳轉(zhuǎn)指令jg的位置。這意味著CPU此時(shí)更傾向于走else分支。

.LC0:
        .string "Positive\n"
.LC1:
        .string "Zero or Negative\n"
main:
        sub     rsp, 8
        test    edi, edi
        jg      .L6
        mov     edi, OFFSET FLAT:.LC1
        call    puts
.L3:
        xor     eax, eax
        add     rsp, 8
        ret
.L6:
        mov     edi, OFFSET FLAT:.LC0
        call    puts
        jmp     .L3

因此,通過(guò)對(duì)分支條件使用likely和unlikely,我們可給編譯器一種暗示,即該分支條件被滿足的概率比較大或比較小。而編譯器利用這一信息優(yōu)化其機(jī)器指令,從而最大限度減少CPU分支預(yù)測(cè)失敗帶來(lái)的懲罰。

likely/unlikely的適用條件

CPU有自帶的分支預(yù)測(cè)器,在大多數(shù)場(chǎng)景下效果不錯(cuò)。因此在分支發(fā)生概率嚴(yán)重傾斜、追求極致性能的場(chǎng)景下,使用likely/unlikely才具有較大意義。

C++20中的likely/unlikely

C++20之前的,likely和unlikely只不過(guò)是一對(duì)自定義的宏。而C++20中正式將likely和unlikely確定為屬性關(guān)鍵字。

int foo(int i) {
    switch(i) {
               case 1: handle1();
                       break;
    [[likely]] case 2: handle2();
                       break;
    }
}

到此這篇關(guān)于C++關(guān)鍵字之likely和unlikely詳解的文章就介紹到這了,更多相關(guān)C++ likely和unlikely內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語(yǔ)言實(shí)現(xiàn)控制臺(tái)五子棋小游戲

    C語(yǔ)言實(shí)現(xiàn)控制臺(tái)五子棋小游戲

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)控制臺(tái)五子棋小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • c語(yǔ)言實(shí)現(xiàn)整蠱朋友小程序(附源碼)

    c語(yǔ)言實(shí)現(xiàn)整蠱朋友小程序(附源碼)

    這篇文章主要給大家介紹了關(guān)于c語(yǔ)言實(shí)現(xiàn)整蠱朋友小程序的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • c++并查集優(yōu)化(基于size和rank)

    c++并查集優(yōu)化(基于size和rank)

    這篇文章主要介紹了c++并查集優(yōu)化(基于size和rank),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • 一篇文章教你用C語(yǔ)言模擬實(shí)現(xiàn)字符串函數(shù)

    一篇文章教你用C語(yǔ)言模擬實(shí)現(xiàn)字符串函數(shù)

    這篇文章主要介紹了C語(yǔ)言模擬實(shí)現(xiàn)字符串函數(shù),開(kāi)發(fā)程序的時(shí)候經(jīng)常使用到一些字符串函數(shù),例如求字符串長(zhǎng)度,拷貝字符串……,需要的朋友可以參考下
    2021-09-09
  • C++中volatile關(guān)鍵字的使用詳解以及常見(jiàn)的誤解

    C++中volatile關(guān)鍵字的使用詳解以及常見(jiàn)的誤解

    volatile 關(guān)鍵字是一種類(lèi)型修飾符,用它聲明的類(lèi)型變量表示可以被某些編譯器未知的因素更改,比如:操作系統(tǒng),硬件或者其他線程等
    2020-01-01
  • Assert(斷言實(shí)現(xiàn)機(jī)制深入剖析)

    Assert(斷言實(shí)現(xiàn)機(jī)制深入剖析)

    言前后最好空一格[編程風(fēng)格的問(wèn)題,按你自已的喜好,適合自已就最好]。斷言只是用來(lái)檢查程序的邏輯正確性,不能代替條件替換。斷言比printf語(yǔ)句這種形式的打印好使
    2013-09-09
  • 超詳細(xì)的c語(yǔ)言字符串操作函數(shù)教程

    超詳細(xì)的c語(yǔ)言字符串操作函數(shù)教程

    字符串是一種重要的數(shù)據(jù)類(lèi)型,有零個(gè)或多個(gè)字符組成的有限串行,下面這篇文章主要給大家介紹了關(guān)于c語(yǔ)言字符串操作函數(shù)的相關(guān)資料,需要的朋友可以參考下
    2021-10-10
  • 用C語(yǔ)言求解第N項(xiàng)斐波那契數(shù)列問(wèn)題

    用C語(yǔ)言求解第N項(xiàng)斐波那契數(shù)列問(wèn)題

    這篇文章主要介紹了用C語(yǔ)言求解第N項(xiàng)斐波那契數(shù)列問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • OpenCV實(shí)現(xiàn)圖像邊緣檢測(cè)

    OpenCV實(shí)現(xiàn)圖像邊緣檢測(cè)

    這篇文章主要為大家詳細(xì)介紹了OpenCV實(shí)現(xiàn)圖像邊緣檢測(cè),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-01-01
  • C/C++實(shí)現(xiàn)string和int相互轉(zhuǎn)換的常用方法總結(jié)

    C/C++實(shí)現(xiàn)string和int相互轉(zhuǎn)換的常用方法總結(jié)

    在C++編程中,經(jīng)常需要在字符串(string)和整型(int)之間進(jìn)行轉(zhuǎn)換,本文將詳細(xì)介紹幾種在C和C++中實(shí)現(xiàn)這兩種類(lèi)型轉(zhuǎn)換的常用方法,有需要的可以參考下
    2024-01-01

最新評(píng)論