Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do the likely/unlikely macros in the Linux kernel work and what is their benefit?

I've been digging through some parts of the Linux kernel, and found calls like this:

if (unlikely(fd < 0)) {     /* Do something */ } 

or

if (likely(!err)) {     /* Do something */ } 

I've found the definition of them:

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

I know that they are for optimization, but how do they work? And how much performance/size decrease can be expected from using them? And is it worth the hassle (and losing the portability probably) at least in bottleneck code (in userspace, of course).

like image 634
terminus Avatar asked Sep 20 '08 23:09

terminus


People also ask

What is the use of likely and unlikely macros in Linux kernel?

Assisting the compiler in optimizing if conditions A look at the Linux kernel code will show many if conditions enclosed in likely and unlikely macros. These macros invoke compiler directives that give the compiler a hint on the code leg that should be optimized for performance.

What is __ Builtin_expect?

You can use the __builtin_expect built-in function to indicate that an expression is likely to evaluate to a specified value. The compiler can use this knowledge to direct optimizations. This built-in function is portable with the GNU C/C++ __builtin_expect function.


1 Answers

They are hint to the compiler to emit instructions that will cause branch prediction to favour the "likely" side of a jump instruction. This can be a big win, if the prediction is correct it means that the jump instruction is basically free and will take zero cycles. On the other hand if the prediction is wrong, then it means the processor pipeline needs to be flushed and it can cost several cycles. So long as the prediction is correct most of the time, this will tend to be good for performance.

Like all such performance optimisations you should only do it after extensive profiling to ensure the code really is in a bottleneck, and probably given the micro nature, that it is being run in a tight loop. Generally the Linux developers are pretty experienced so I would imagine they would have done that. They don't really care too much about portability as they only target gcc, and they have a very close idea of the assembly they want it to generate.

like image 151
1800 INFORMATION Avatar answered Sep 21 '22 17:09

1800 INFORMATION