Live data from Hacker News

C++ Attribute: Likely, Unlikely

en.cppreference.com

31–40 of 70 posts

Re: C++ Attribute: Likely, Unlikely

#31

See also: https://blog.aaronballman.com/2020/08/dont-use-the-likely-or... tl;dr: these attributes are absolutely full of footguns because the standard is not explicit about precedence and nesting, and you should probably avoid them and prefer to spend time investing in PGO. It’s very easy to make sane-looking code containing these attributes which does the exact opposite of what you intended. Note that this issue doe…

If someone is going to go crazy and try mark the likelihood of all paths in their code then they clearly don't understand the feature.

That doesn't mean it shouldn't exist and isn't useful.

Re: C++ Attribute: Likely, Unlikely

#32
post #10

Earlier quoted context omitted.

And even then they should be handled with extreme care, as they can trigger UB if used incorrectly.

Do you have examples? It's not clear from the article how you could have a UB with them.

If I remember correctly, Timur Doumler does some remarks on that sense on his presentation:

"Standard Attributes in C and C++"

https://youtu.be/TDKqAWtvH9c?si=b5quQkMe7XUvBbG7

Re: C++ Attribute: Likely, Unlikely

#33
I often write my code pessimally in this regard so have a note in the back of my mind to someday use these in a few hot paths.

When I say “pessimally” I mean I usually check the unlikely cases right away and then put the normal case last:

    Blah foo (something& arg) {
    
      if (is_invalid  (arg)) return blah(0);
      if (is_inactive (arg)) return blah(1);
    
    // ok do all the normal stuff
    }
It makes the code clearer but slightly slower. I could always write a conditional for the hot path up front, but code is for human readers, right?

So when people say “this clutters the code” they are right, but most of the time you just don’t worry about it — it need only clutter a few functions in your hot loops, where you’re willing to rewrite it anyway regardless of how ugly it gets.

It’s like looking at the standard library source: super cluttered, but it has to handle all sorts of weird corner cases and is called a lot. Normal code can ignore all that in more than 99.99% of the cases.

Re: C++ Attribute: Likely, Unlikely

#35

What everybody should read before using these (Aaron Ballman is a Senior Staff Compiler Engineer for Intel and is the lead maintainer of the Clang open source compiler): https://blog.aaronballman.com/2020/08/dont-use-the-likely-or...

I loved it! Thanks! The last part resumes my thinking: These attributes are starting to look a bit more like some other code constructs we’ve seen in the past: the register keyword as an optimization hint to put things in registers and the inline keyword as an optimization hint to inline function bodies into the call site. Using register or inline for these purposes is often strongly discouraged because experience has shown … My take is: 99.9% of the time, when you start shaving some CPU cycles here and there, instead of doing algorithmic optimization, something is going wrong.

Re: C++ Attribute: Likely, Unlikely

#36

What everybody should read before using these (Aaron Ballman is a Senior Staff Compiler Engineer for Intel and is the lead maintainer of the Clang open source compiler): https://blog.aaronballman.com/2020/08/dont-use-the-likely-or...

It's an odd article. The basic thesis is "use pgo instead", which is reasonable enough. It starts with a long diversion through edge cases of the attributes, none of which seemed particularly impactful in practice. Perhaps he was worried that just recommending pgo on its own wouldn't convince many people. There are many situations where you can't enable pgo organizationally, for example if you're part of a large company with a centralized build system, or if you package a library meant to be inlined, and want your code to be optimized even when it's built without pgo. The comparison to `register` and `inline` are interesting, but not very useful imo. Whether a given variable will benefit from being put in a register, or a function from being inlined, is usually very local information. The compiler can see when the variable will be accessed down the road, and hence whether moving it to the stack will tend to slow down later code. Whether a branch is likely or unlikely will frequently depend on information the compiler doesn't have (sans pgo), such as the distribution of an argument variable. In fact, it seems like this very information would be useful to a compiler in determining if it should inline a function or keep a variable in a register.

Re: C++ Attribute: Likely, Unlikely

#37
post #33

I often write my code pessimally in this regard so have a note in the back of my mind to someday use these in a few hot paths. When I say “pessimally” I mean I usually check the unlikely cases right away and then put the normal case last: Blah foo (something& arg) { if (is_invalid (arg)) return blah(0); if (is_inactive (arg)) return blah(1); // ok do all the normal stuff } It makes the code clearer but slightly slowe…

Names like 'is_invalid' and 'is_inactive' will lead to a double negation.

Re: C++ Attribute: Likely, Unlikely

#38
post #33

I often write my code pessimally in this regard so have a note in the back of my mind to someday use these in a few hot paths. When I say “pessimally” I mean I usually check the unlikely cases right away and then put the normal case last: Blah foo (something& arg) { if (is_invalid (arg)) return blah(0); if (is_inactive (arg)) return blah(1); // ok do all the normal stuff } It makes the code clearer but slightly slowe…

> I usually check the unlikely cases right away and then put the normal case last.

Don't we all?

Re: C++ Attribute: Likely, Unlikely

#40
post #33

I often write my code pessimally in this regard so have a note in the back of my mind to someday use these in a few hot paths. When I say “pessimally” I mean I usually check the unlikely cases right away and then put the normal case last: Blah foo (something& arg) { if (is_invalid (arg)) return blah(0); if (is_inactive (arg)) return blah(1); // ok do all the normal stuff } It makes the code clearer but slightly slowe…

I'm so confused by this. How would you avoid doing these checks? Aren't they invariants for your function?
Post reply on HN