Live data from Hacker News

C++ Attribute: Likely, Unlikely

en.cppreference.com

41–50 of 70 posts

Re: C++ Attribute: Likely, Unlikely

#41
post #32

Earlier quoted context omitted.

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

Could you least give some timestamps? It's nearly two hours.

Anyway, while it is possible that some attributes can cause UB if misused, I very much doubt that's possible with [[likely]] and [[unlikely]], as they are just hints for the optimizer, and the optimizer is supposed to preserve semantical guarantees.

Re: C++ Attribute: Likely, Unlikely

#42
post #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.

Agreed, this reads so much easier...

  if (!is_valid)

  if (!is_active)

Re: C++ Attribute: Likely, Unlikely

#43
post #30

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…

PGO is not a silver bullet. If you've identified a problem that can be solved by a simple static hint you should do that. I agree littering your code with likely/unlikely will probably make things worse, so it's best to save them for those exceptional cases where you know it will make an improvement.

It's not a silver bullet but PGO does subsume these hints. Consider what do you do if PGO conflicts with your static hints? My hypothesis is that in that case the static hint is most likely incorrect and contributing to slower code.

So either you aren't using PGO at all, which is fine if squeezing out these kinds of optimizations isn't that important to you, but then what's the point having these static hints?

Or you are using PGO, in which case there's no point in having these static hints because PGO will identify the likely and unlikely scenarios on your behalf. If PGO doesn't identify likely and unlikely branches, then the reason is because your profile isn't representative of how your program will actually be run in production, but in that case the solution is to provide a more representative profile instead of using [[likely]] and [[unlikely]].

Re: C++ Attribute: Likely, Unlikely

#44
post #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?

I don’t think they suggested avoiding the checks, unless I’ve missed something?

Re: C++ Attribute: Likely, Unlikely

#45

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 think that everybody should instead read proposal that introduced this feature, P0479R2[1]

[1] https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p04...

and look at code in the wild

[2] https://github.com/search?q=[[likely]]+language%3Ac%2B%2B&ty...

Re: C++ Attribute: Likely, Unlikely

#46

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 comp…

> Whether a branch is likely or unlikely will frequently depend on information the compiler doesn't have (sans pgo),

Exactly! Often it is simply impossible for the compiler to know. In this respect it is similar to std::unreachable.

Re: C++ Attribute: Likely, Unlikely

#47
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 could always write a conditional for the hot path up front, but code is for human readers, right?

Does C or C++ actually make any promises that it’ll assume the “true” branch of the conditional will be taken? I always assumed that the compiler could make whatever weird decision it wants for that sort of thing.

TBH I’d probably just write normal stuff as a function, and then call that function directly in cases where performance is really crucial, if it can be done safely… if such a case exists…

Re: C++ Attribute: Likely, Unlikely

#48
post #40

Earlier quoted context omitted.

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

I don’t think they suggested avoiding the checks, unless I’ve missed something?

Maybe the implied question is that, the compiler can optimise the checks to the occur in whatever order it wants.

Re: C++ Attribute: Likely, Unlikely

#49
post #40

Earlier quoted context omitted.

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

I don’t think they suggested avoiding the checks, unless I’ve missed something?

The part that's confusing me is the part about avoiding clutter – if you have to do all the checks anyway, what clutter are you avoiding by changing the order of them?

Re: C++ Attribute: Likely, Unlikely

#50
post #11

In GCC you can already use (both on functions¹ and labels²) __attribute__(hot) and __attribute(cold) 1. https://gcc.gnu.org/onlinedocs/gcc-13.2.0/gcc/Common-Functio... >; Since GCC 4.3, released March 5, 2008 2. https://gcc.gnu.org/onlinedocs/gcc-13.2.0/gcc/Label-Attribut... >; Since GCC 4.8, released March 3, 2013

The typical expansion of pre attribute likely/unlikely macros (for example from the linux kernel) is buitin_expected. Hot/cold should also work if a bit extreme.

Note that those are ultimately dealing with different concepts:

likely/unlikely are ultimately about branches - predict that a likely branch is taken and an unlikely branch is not taken. Note that there is some default logic in GCC even if the branches aren't tagged (for example, pointers are assumed to usually not be NULL). Failing that it usually generates the code in the order the source was laid out, but I don't think there's any "probability" weight here, just inertia, so it's easy for the optimizer to change it even by accident.

Note that the default probabilities are 90% and 10% (I've seen other software use 93.75% = 15/16); you can specify other probabilities if meaningful. Notably, choosing 50% encourages the generation of `cmov`.

hot/cold is ultimately about code size and section layout. Keep the hot code sections in cache, keep the cold code sections out of cache (and optimize it for size more than speed). Branches from non-cold to cold code are automatically tagged unlikely (not sure about hot to non-hot, or cold to anything), which is what makes people think they're related.

Post reply on HN