常看到内核中的代码如下:
如果你眼睛够细会看到likely 和 unlikely 这样的词. 在内核中它应该不是函数, 要是函数也应该是inline, 不过我觉得它更应该是一个宏
通过SI读源码, 可以看到它们被定义如下:
__builtin_expect作用是gcc内建的一条指令的优化,在一个条件经常出现, 或者该条件很少出现的时候, 编译后可以根据这条指令对条件分支选择优化
__builtin_expect((x),1)的意思是
表示这个if里面为真, 程序大多数直接执行if里面的程序
__builtin_expect((x),0) 则和上面相反直接执行else里面的程序.
来看段程序:
然后看它汇编代码, 使用gcc -O2 -fprofile-arcs 来进行编.
可以看出相同的程序,不同的likely的情况下, 程序分别使用了je和jne进行了优化.
对于编译代码的时候使用-fprofile-arcs , 原因如下:
Built-in Function: long __builtin_expect (long exp, long c)
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 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))
foo (*ptr);when testing pointer or floating-point values.