Understanding likely and unlikely in the Linux Kernel

In the Linux kernel source code, the keywords likely and unlikely are frequently encountered. Upon examining the source code, it turns out that these two keywords are macros defined in the include/linux/compiler.h file of the kernel source (specifically in linux-3.11.0-rc1):

Since CONFIG_PROFILE_ALL_BRANCHES is not defined, the definitions of the two macros are as follows:

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

Here, __builtin_expect is a built-in function of gcc, primarily used for branch prediction optimization. It places the code segment that is likely to be executed after the conditional check, optimizing the binary content of the code, making it more compact and improving execution efficiency while avoiding inefficiencies caused by excessive branching. (For a detailed explanation of this function, visit http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html)

For example:

if (__builtin_expect(!!(x), 1)) {    A} else {    B}

From the code, it indicates that the probability of the condition being true is higher, and the program will mostly execute the A code segment. If we change 1 to 0, then the program will mostly execute the B code segment. In this case, the high-probability code segment is directly represented in assembly as following the condition. You can visit http://kernelnewbies.org/FAQ/LikelyUnlikely to see corresponding examples.

Transforming the above condition into likely(x) and unlikely(x) corresponds exactly to the analysis above. However, the macros include !!(x); what is its purpose? It mainly checks whether the comparison value is 0 or 1. Here, it converts the incoming x to a boolean type by negating it and then negating it again to restore the original x to a boolean value, representing false and true in the form of 0 and 1. Since non-zero values are considered true, but when comparing non-zero values with 1, it is difficult to confirm they are true. Therefore, double negation is used to narrow down the judgment value for boolean evaluation.

Leave a Comment