Using likely/unlikely Macros for Performance Optimization in the Linux Kernel
This article explains how the Linux kernel’s likely and unlikely macros, which wrap GCC’s __builtin_expect, guide branch prediction to improve cache utilization and pipeline efficiency, and demonstrates their impact with sample code and assembly analysis.
The article introduces the likely and unlikely macros commonly used in the Linux kernel to hint the compiler about the most probable execution path, thereby aiding branch prediction.
1. likely and unlikely
Both macros are simple wrappers around GCC's __builtin_expect :
#define likely(x) __builtin_expect(!!(x),1)
#define unlikely(x) __builtin_expect(!!(x),0)When the compiler sees these hints, it can arrange the generated code so that the most likely branch follows the conditional check, reducing the number of jumps and improving instruction cache locality.
2. Practical verification
A minimal test program demonstrates the effect:
#include
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
int main(int argc, char *argv[]){
int n = atoi(argv[1]);
if (likely(n == 10)){
n = n + 2;
} else {
n = n - 2;
}
printf("%d\n", n);
return 0;
}Compiling with -O2 and inspecting the assembly (using objdump -S ) shows that the likely branch places the n = n + 2 instructions immediately after the comparison, while the alternative path is placed farther away. Reversing the macro to unlikely swaps the layout.
3. Performance improvement principles
The performance gain stems from two main CPU mechanisms:
Cache behavior: Modern CPUs have multi‑level caches (L1, L2, L3). Placing the most probable instructions close together increases the chance they reside in the fast L1 cache, avoiding costly fetches from lower‑level caches.
Pipeline efficiency: CPUs execute instructions in a pipeline. When the predicted branch is correct, the pipeline stays filled; a misprediction forces a pipeline flush, wasting cycles.
By aligning the hot path with the likely branch, both cache hits and pipeline utilization improve.
4. Summary
The likely and unlikely macros are lightweight compiler hints that help the CPU’s branch predictor, leading to higher cache‑hit rates and smoother pipeline execution. Correctly applying them in performance‑critical kernel code can yield measurable speedups, but inaccurate predictions may degrade performance.
IT Services Circle
Delivering cutting-edge internet insights and practical learning resources. We're a passionate and principled IT media platform.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.