26

I came across these 2 macros in Linux kernel code. I know they are instructions to compiler (gcc) for optimizations in case of branching. My question is, can we use these macros in user space code? Will it give any optimization? Any example will be very helpful.

jww
  • 97,681
  • 90
  • 411
  • 885
Vinit Dhatrak
  • 6,814
  • 8
  • 27
  • 30
  • http://kerneltrap.org/node/4705 – pmg Nov 03 '09 at 15:29
  • duplicate? http://stackoverflow.com/questions/109710/likely-unlikely-macros-in-the-linux-kernel – Aleksei Potov Nov 03 '09 at 15:34
  • I checked these posts, but both again talks about kernel related stuff. I wanted to know whether same can be used in user code. – Vinit Dhatrak Nov 03 '09 at 15:38
  • If you are programming for any reasonably powerful processor, you are unlikely to get any performance benefit. Modern dynamic branch predictors are quite good. – Jay Conrod Nov 03 '09 at 15:50
  • @Jay I think programmer should not assume power of processor. Dynamic branch detection would be easier if programmer explicitly provide the information. – Vinit Dhatrak Nov 04 '09 at 12:40
  • @vinit, i create a random vector(from 0-100, branch is bigger than 0 or not) to measure "likely" brings performance gain compared branch prediction of CPU. Result shows it's similar time cost with or without likely. – Tongxuan Liu Sep 18 '16 at 07:35

3 Answers3

44

Yes they can. In the Linux kernel, they are defined as

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

The __builtin_expect macros are GCC specific macros that use the branch prediction; they tell the processor whether a condition is likely to be true, so that the processor can prefetch instructions on the correct "side" of the branch.

You should wrap the defines in an ifdef to ensure compilation on other compilers:

#ifdef __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

It will definitely give you optimizations if you use it for correct branch predictions.

SamB
  • 9,039
  • 5
  • 49
  • 56
Tomas
  • 5,067
  • 1
  • 35
  • 39
  • 1
    In the #else part, shouldn't they evaluate to (x) and not empty? – Laurynas Biveinis Nov 03 '09 at 15:33
  • which header file contains this definition in user include directories ? – Vinit Dhatrak Nov 03 '09 at 15:40
  • @tonfa i dont want kernel's header file. I want file which is in /usr/include so that I can include it in my user space code. – Vinit Dhatrak Nov 03 '09 at 15:46
  • 1
    They are only available in the kernels header file (or maybe in other projects). I suggest you create your own header file and add the definitions above. __builtin_expect is a gcc builtin and doesn't need an addition header file. – Tomas Nov 03 '09 at 16:52
  • 8
    You should use !!(x) instead of just (x), to force the parameter to be converted to either 0 or 1. – CesarB Aug 13 '11 at 23:01
12

Take a look into What Every Programmer Should Know About Memory under "6.2.2 Optimizing Level 1 Instruction Cache Access" - there's a section about exactly this.

Nikolai Fetissov
  • 82,306
  • 11
  • 110
  • 171
4

The likely() and unlikely() macros are pretty names defined in the kernel headers for something that is a real gcc feature

Ken Bloom
  • 57,498
  • 14
  • 111
  • 168