2019年2月6日 星期三

likely,unlikely宏與GCC內建函數__builtin_expect()

Source https://blog.csdn.net/mopyman/article/details/595302

在讀linux/kernel/fork.c的時候遇到了unlikely宏定義,一路追蹤,最後找到了GCC內建函數__builtin_expect(),查閱GCC手冊,發現其定義如下:
long __builtin_expect (long exp, long c)                                    [Built-in Function]
You may use __builtin_expect to provide the compiler with branch prediction
information. In general, you should prefer to use actual profile feedback for this
(‘-fprofile-arcs’), as programmers are notoriously bad at predicting how their
programs actually perform. However, there are applications in which this data is
hard to collect.
The return value is the value of exp, which should be an integral expression. The
value of c must be a compile-time constant. The semantics of the built-in are that it
is expected that exp == c. For example:
if (__builtin_expect (x, 0))
foo ();
would indicate that we do not expect to call foo, since we expect x to be zero. Since
you are limited to integral expressions for exp, you should use constructions such as
if (__builtin_expect (ptr != NULL, 1))
error ();
when testing pointer or floating-point values.
大致是說,由於大部分程序員在分支預測方面做得很糟糕,所以GCC提供了這個內建函數來幫助程序員處理分支預測,優化程序。其第一個參數exp為一個整型表達式,這個內建函數的返回值也是這個exp,而c為一個編譯期常量,這個函數的語義是:你期望exp表達式的值等於常量c,從而GCC為你優化程序,將符合這個條件的分支放在合適的地方。
因為這個程序只提供了整型表達式,所以如果你要優化其他類型的表達式,可以採用指針的形式。

unlikely的定義如下:
#define unlikely(x)  __builtin_expect(!!(x), 0)
也就是說我們期望表達式x的值為0,從而如果我們用
…….
if(unlikely(x)){
bar();
}來測試條件的話,我們就不期望bar()函數執行,所以該宏的名字用unlikely也就是不太可能來表示。
likely宏與次類似.
說到底__builtin_expect函數就是為了優化可能性大的分支程序。

沒有留言: