Date: Thu, 15 Aug 2024 22:12:09 +0200
Hi Robin,
a) was not meant for you to write ad-hoc unit tests, whenever you find slower-running code, but to submit beforehand, if this always happens with typical cases (at least for certain compilers), then their optimizer could be improved (fixed) and no change to the C++ standard would be needed and every program and programmer would profit from the speed-up without any changes in the programs.
If this is not possible, because some compiler vendors would not improve their optimizer, but would still follow new C++ standards, then a) is not enough.
If this is not possible, as some use cases are too involved and cannot be guessed beforehand and be submitted as typical cases, then a) is not enough.
b) Attributes are nice, as (in their pure form, if defined by the standard (and not be about unique address)) they can be left out without any change in program semantics. They are very suitable for performance hints and there is already precedent, see https://en.cppreference.com/w/cpp/language/attributes/likely
IMHO for this case performance hints would be rather accepted in this case.
Your library function is not a simple library function, as it wants to enforce a certain translation into machine code.
If this is enforced, it could complicate translation, as on some platforms optimizer steps run automatically and overrides would have to be introduced, which are kept in intermediary formats.
If the library function is still meant as a hint not to shortcut or even not to branch at all, then there is still the disadvantage that the same semantics is formulated differently with () or without (&&) library function.
With ever better optimizers, C++ programming should be careful, when and how the as-if rule is broken. There are very few exceptions in the language. On the top of my head, I only can think of volatile for memory accesses and I/O (which on many µC platforms is also a memory access as there is no separate I/O address space).
Those breaks from the as-if rule are real pain points and should be carefully chosen. I do not think it is worth it beyond attributes = solution b)
c) From a) to d) I go further and further from my advice on the end. However, if your intended outcome can be achieved with existing means (? ternary operator) or (? non-shortcut and) or (* multiplication of implicitly converted logical values) then the question is, whether a new library function should be introduced. Even more so, if the library function does not enforce it (and just delivers a hint) in order not to be a pain point for the optimizer and the as-if rule.
Best,
Sebastian
-----Ursprüngliche Nachricht-----
Von:Robin Savonen Söderholm <robinsavonensoderholm_at_[hidden]>
Gesendet:Do 15.08.2024 21:41
Betreff:Re: [std-proposals] No shortcut logical operands-functions
An:std-proposals_at_[hidden];
CC:Sebastian Wittmeier <wittmeier_at_[hidden]>;
@Sebastian:
a) Yes, it would be fantastic if the optimiser could solve all such problems for us. However, that is not always the case. The problem, I think, is that it is very difficult to know beforehand when shortcutting is good or not. And it may even be a question about average vs. worst-case time tradeoff. Doing a realtime system, we may be more interested in the worst-case scenario and thus, always want shortcuts gone when possible. And even if this case if feasible in theory, it becomes a very long loop to improve my program if I first must create a unit-test that shows sub-optimal code that (hopefully) pinpoints the exact problem that I have and then wait for the vendor to release a new version with the unit-test fixed. Quicker if I can try to eliminate branches myself directly when profiling various things. Also, sometimes I have to work with compilers with questionable quality, and at those times I prefer to have the ability to choose certain things myself when I have to.
b) Attributes could work, but would they not be part of the compiler rather than the library? I was led to believe that extending the library is easier than the compiler, thereby my approach of adding it as either functions or generator expressions.
c) Personally, I think this one goes against what you stated after the list: here we suddenly *need* to change our code to something similar-but-not-quite looking thing in *hopes* that the compiler will do what we hope, rather than allowing us to explicitly state "hey, at this exact line, I need you to do this". Besides, the expression inside the '{}' may be more complicated, making the `?`-syntax not viable.
But I do whole-heartly agree that using this carelessly can definitely be pessimations rather than optimisations at times, but so can constantly using "const &" rather than pass-by-value-and-move be as well.
Received on 2024-08-15 20:12:12