C language trick: use likely and unlikely with if to make the code run faster

In single-chip/embedded programming, the speed requirements are relatively high. Likely and unlikely are a better technique, which is suitable for situations where there are if-else branches and you know which one has a higher probability of occurrence​.

Reference article: C language skills: use likely and unlikely with if to make the code run faster

1.likely和unlikely

These are two macros that tell the compiler which condition is more likely to occur when there is an if-else branch. Optimize the if-else branch structure. Likely means that the if branch has a high probability of happening, and unlikely means that the if branch has a high probability of not happening.

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

__builtin_expect is a compiler built-in function whose prototype is long __builtin_expect (long exp, long c).

Off-topic: !! is a technique for processing logical expressions in C language. Because there are no boolean variables in C language, boolean values ​​are replaced by integers, 0 is false, and non-zero is true. When x is 0, !(x) is 1, !!(x) is 0, and the operation of !! has no meaning; but when x is non-zero (such as 100), !(x) is 0, !! (x) is 1, which achieves the effect of mapping all non-zero values ​​(such as 100) to 1.

example:

​If there is such a function:

int fun(int a){
   
     if(a>100)  ......}

In actual operating conditions, a>100 is unlikely to happen. Then write it like this:

int fun(int a){
   
     if(unlikely(a>100))  ......}

Similarly, if the actual situation is that a>100 is more, use ​likely.

2. Note

1. The use of likely and unlikely must be judged accurately, and reverse writing will slow down the running speed.

2. Compile-time optimization generally needs to use at least the -O2 option, otherwise the optimization will not work.

3. Whether it can be used is related to the compiler, gcc can, clang seems to be able to, msvc seems not to be able to.

3. Principle

When the compiler compiles and generates assembly code, it will adjust the position of the code in the if branch under the guidance of the compilation options. If it is likely modified, it will be adjusted to the front, and if it is unlikely modified, it will be adjusted to the back. Putting the code in the front can save the time overhead caused by the jump instruction, so as to achieve the purpose of improving efficiency.

Current CPUs have ICache and pipelining mechanisms. When running the current instruction, ICache will prefetch the following instructions to improve operating efficiency. But if the conditional branch is not satisfied, it will jump to other instructions, and the prefetched instructions will be useless, which will reduce the efficiency of the pipeline.

If you use likely and unlikely to tell the compiler which is more likely to happen, the compiler will put the code with a high probability of execution in the front position, which can greatly improve the hit rate of instruction prefetch values, thereby achieving the purpose of improving efficiency.

 

Guess you like

Origin blog.csdn.net/freestep96/article/details/128771498