Use Branch Prediction Hints in C

Use Branch Prediction Hints in C

Some conditional branches occur far more frequently than others. In code where performance is critical, it can be useful to communicate these expected execution patterns to the compiler. This allows the compiler to arrange generated code with the common path in mind and may reduce the cost of frequently executed branches.

C itself does not provide a standard mechanism for specifying whether a condition is expected to be true or false. GCC and Clang provide __builtin_expect for this purpose. When compiler-specific support is unavailable, the condition can simply be evaluated normally without applying any prediction hint.

A small example can illustrate the idea:

#include <stdio.h>

#if defined(__GNUC__)
#define LIKELY(x)   __builtin_expect(!!(x), 1)
#define UNLIKELY(x) __builtin_expect(!!(x), 0)
#else
#define LIKELY(x)   (x)
#define UNLIKELY(x) (x)
#endif

int is_adult(const int age) {
    if (UNLIKELY(age < 0)) {
        return 0;
    }
    if (LIKELY(age >= 18)) {
        return 1;
    }

    return 0;
}

int main(void) {
    printf("%d\n", is_adult(30)); // 1
    printf("%d\n", is_adult(10)); // 0
    printf("%d\n", is_adult(-5)); // 0

    return 0;
}

The LIKELY macro indicates that a condition is expected to evaluate to true in normal execution, whereas UNLIKELY marks a condition that is expected to be false most of the time. In the example, an adult age is treated as the common case, while a negative age is considered an exceptional input.

Keep in mind that branch prediction hints should represent realistic execution frequencies rather than simply marking branches based on their assumed importance. Modern compilers and processors already perform significant branch optimization, so an incorrect hint can potentially make generated code less efficient instead of improving it.

Leave a Comment

Cancel reply

Your email address will not be published.