C++ Logo

std-proposals

Advanced search

Re: [std-proposals] No shortcut logical operands-functions

From: Robin Savonen Söderholm <robinsavonensoderholm_at_[hidden]>
Date: Thu, 15 Aug 2024 21:40:52 +0200
@Marcin: Yes exactly, a bitwise-operation (or even an '*') may save us from
the extra branch.

@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.

@Jens: It is hard to say how often this may be a problem. But I can
understand the point that it may not be a problem often enough that we need
a standardized way of dealing with it. It's just that if I need to
implement it myself, I have to check for all compilers that I use that my
function does not generate unwanted branches, and I may even need to use
macros and if-defs to create vendor-specific workarounds to force the
wanted behaviour. If I were on the other hand to implement this in a
standard library used by a single compiler vendor, then the task becomes
simpler (maybe not as much as I'd hoped though since both GCC:s and MSVC:s
standard library implementations are used by Clang as well..)

// Robin

On Thu, Aug 15, 2024 at 9:15 PM Sebastian Wittmeier via Std-Proposals <
std-proposals_at_[hidden]> wrote:

> How to tackle this:
>
>
>
> a) One could just try to improve the optimizers:
>
> Create a lot of examples (unit tests) and file reports to the compiler
> vendors, where the code with -O3 is not optimal.
>
>
>
> b) Request the speed improvement with an attribute; if the optimizer does
> not manage, a warning is output at that line of code.
>
>
>
> c) If you want to change the code to not create conditional jumps, I would
> not start with the condition, but with the if clause.
>
> Change it to return (a > 0 && b != 0) ? 0 : 1;
>
>
>
> d) Only if that is not enough and perhaps Marcin's hint of using &, then I
> would think of introducing new ways to state the condition.
>
>
>
>
>
> The think is, the logic of the code stays the same; a good compiler should
> not care how the logic is formulated, if it basically is identical in
> meaning.
>
>
>
> Introducing new ways, which enforce some kind of translation into machine
> code, would limit a lot, what the optimizer may still do. Your idea could
> lead to a pessimization, if e.g. a > 0 does not have to be tested for at
> all at that point and the new construct enforces a certain translation.
> Examples could be more extreme, even spanning function calls - perhaps the
> function can be inlined, and the return would never be executed. Or one
> conditional jump is enough to avoid 5 others and you prevent it.
>
>
>
> So I would start with performance hints before going into stricter
> enforcements.
>
>
>
> Best,
>
> Sebastian
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>

Received on 2024-08-15 19:41:28