8

X is true nearly 99.9% of the time but I need to handle Y and Z as well. Although the body of the X condition is empty, I'm thinking it should be faster than potentially checking 2 other conditions Y and Z if the X condition is omitted. What do you think?

if (likely(X))
{
}
else if (unlikely(Y))
{
...
}
else if (unlikely(Z))
{
...
}
chriskirk
  • 761
  • 1
  • 11
  • 22

4 Answers4

11

You might want to know what exactly happens when you use likely or unlikely:
http://kerneltrap.org/node/4705

I would personally write

if (unlikely(!X))
{
  if (unlikely(Y))
  {
  ...
  }
  else if (unlikely(Z))
  {
   ...
  }
}

Which means if x, continue execution, else jump to if body.

log0
  • 10,489
  • 4
  • 28
  • 62
8

As usual, when in doubt profile; anyhow, if I were to read that code I would find much clearer something like:

if (!likely(X))
{
    if (unlikely(Y))
    {
    ...
    }
    else if (unlikely(Z))
    {
    ...
    }
}
Matteo Italia
  • 123,740
  • 17
  • 206
  • 299
  • 1
    I am not really sure that the negation of unlikely will work as expected ?? I would rather write `unlikely(!x)`. This means that there will be no jump if `x` is false. – log0 Jan 19 '12 at 21:58
  • @Ugo I like the solution posted by Matteo and I rewrote it using your unlikely(!x) instead. – chriskirk Jan 19 '12 at 22:01
  • @Ugo: I assumed that `likely(X)` was the whole condition to be evaluated, as in his pseudocode... still, the point I'm making should be clear. – Matteo Italia Jan 19 '12 at 22:15
  • 2
    @MatteoItalia: `likely` and `unlikely` are macros provided by GCC that wraps compiler specific builtins that *hint* to the compiler whether a condition is likely or not. (gcc's is `__builtin_expect` I think) – Matthieu M. Jan 20 '12 at 07:25
1

If a compiler is to assume, it would generally favor the first condition true.

you can use something like __builtin_expect to control this (as Ugo detailed).

If it's in a loop, you should measure because hardware is also a consideration -- it's not just the source and the compiler. How's your cache, and how's branch prediction working for you? Profile. Alter. Profile. Compare.

justin
  • 104,054
  • 14
  • 179
  • 226
0

Do you really need the unlikely's on y and z? It sounds from your question like if x is not true, then y or z must be true, in which case those unlikely's are incorrect and I would go with this:

if (unlikely(!X))
{
  if (Y)
  {
  ...
  }
  else //Z must be true
  {
   ...
  }
}

(Would have made this a comment on Ugo's answer, but I don't have enough reputation to leave comments.)

MikeFHay
  • 8,562
  • 4
  • 31
  • 52