Some software (often performance-oriented, e.g. Linux kernel, DPDK) has C helpers for influencing branch prediction.
I have an absolutely simple code snippet (suppose I know the percantage of a > b) to represent the problem of conditions nesting and applying likely
/unlikely
when some logic is nested:
bool foo()
{
foo1(1);
foo2(2);
/* if (unlikely(a > b)) */
/* if (a > b)*/
{
puts("Ohhh!!! Rare case");
return true;
}
return false;
}
int main(void)
{
/* if (unlikely(foo())) */
/* if (foo()) */
{
puts("Azaza");
}
}
So which 2 lines should be uncomented for more performance from a theoretical point of view?
Obviously there are 3 ways to assist compilier with branch prediction:
1.
if (unlikely(a > b))
...
if (unlikely(foo()))
2.
if (a > b)
...
if (unlikely(foo()))
3.
if (unlikely(a > b))
...
if (foo())
Which is theoretically the most efficient and why?
foo()
here. Then again, it would probably not hurt to add it to theif
inmain
too. – Wampumfoo
should be written as simplyreturn a > b;
, without any branches. If you have more code than justreturn
in theif/else
then it's fine, but in that case of course thelikely
should be infoo
. – Diaphoresismain()
too? Btw - a bit edited the code :) – Reasonablemain
too. The compiler might be smart enough to not need it if it inlinesfoo
, but it won't hurt. – Diaphoresismain()
, IMHO it's better to cut off the wrong branch of execution earlier. – Reasonablefoo
happens earlier than the check inmain
– DiaphoresisIt is more logical to assume that first of all it should be in main()
- likely/unlikely is for predicting the outcome of a single branch. You have two branches here. If you add likely/unlikely to one, the other still remains unoptimized. In theory compilers might be able to make an inference of the connection or make the function inline, but unless you know that it does happen, I wouldn't rely on it. – Tret