天天看點

【glibc】淺析 __builtin_expect

大約一年之前看過,今天又看了一遍。總結一下。

對于程式員來說,有時我們是知道if判斷之後最有可能會去執行哪個分支的。

對于CPU而言,流水線機制使得CPU會在執行目前指令時,就已經會完成對下一條指令的取指操作。如果下一條已經取出來的指令沒有被執行,取指操作就浪費了!如果執行了,就節省了取指令的操作。

為了不讓CPU浪費取指操作,我們需要讓執行if判斷後,下一條指令是最有可能被執行的指令。對應到彙編,就是jmp的下一條指令,最好要被執行。是以誕生了 __builtin_expect指令。

在C語言中,if(a){printf("1");else{printf("0");}}。假設程式員知道a很有可能是True,為了提高效率,就增加 __builtin_expect。寫成if( __builtin_expect(!!(x),1)),那麼編譯器在彙編時會把printf("1");放在jmp語句的下面,這樣就節省了效率。

$ cat  buildinexpect.c
#include <stdio.h>

void Amight1(int a){
    if(__builtin_expect(a,1)){
        printf("a is 1\n");
    }
    else{
        printf("a is 0\n");
    }
}

void Amight0(int a){
    if(__builtin_expect(a,0)){
        printf("a is 1");
    }
    else{
        printf("a is 0");
    }
}


int main()
{
    int a;
    a = 1;
    printf("Hello world\n");
    Amight1(a);
    a = 0;
    Amight0(a);
    return 0;
}
           

編譯:gcc -fprofile-arcs -O2 -c buildinexpect.c

檢視反彙編:objdump -d buildinexpect.o -M intel

最有可能執行的放在jmp語句的後面。

【glibc】淺析 __builtin_expect

參考:https://blog.csdn.net/shuimuniao/article/details/8017971

PWN c