August 27
On 8/26/2024 10:39 PM, Manu wrote:
> Your suggestions could appear in almost every single at-least-warm function, and it's not clear how they marry with eachother. We discussed 2 principle cases; likely early return because of short-path or cached value, and unlikely early return due to argument validation failure. Plenty of functions contain both cases, and plenty of functions contain numerous such items.
> Try and imagine how your suggestion scales when there are 4-5 conditions that need to be tested on function entry, and they don't all receive the same hint. I value readable and maintainable code...

For reference, a real world example of your code?
August 28
On Friday, 23 August 2024 at 17:39:39 UTC, Manu wrote:
> Validations are usually a series of exclusionary checks framed as
> `if(fails_validity_check) return;`
> That flow keeps code in a nice linear flow, it doesn't introduce any scopes

Aren't returns grouped near the end of function? Then validation checks would be implemented as forward jumps, which at least riscv interprets as unlikely by default.
August 28
I'm not sure what you mean? In my experience, returns are generally grouped at the top.

void f(int x)
{
  if (x < 0)
    return;

  do;
  if (do.error)
    return;

  some;
  work;
}

In lieu of any hinting, the if is assumed true; so the compiler will branch over the return in the nominal case.

You would need to write this to fix that bad prediction:

void f(int x)
{
  if (x >= 0)
  {
    do;
    if (!do.error)
    {
      some;
      work;
    }
  }
}

You can see how the function body will accumulate unmitigated scopes now.
That's just straight up bad code. (Linus would sack me on the spot if I
wrote that!)
It's not at all unlikely to find functions that have several such checks in
series... I won't write code that's an ugly sea of nesting.

On Wed, 28 Aug 2024 at 19:01, Kagamin via Digitalmars-d < digitalmars-d@puremagic.com> wrote:

> On Friday, 23 August 2024 at 17:39:39 UTC, Manu wrote:
> > Validations are usually a series of exclusionary checks framed
> > as
> > `if(fails_validity_check) return;`
> > That flow keeps code in a nice linear flow, it doesn't
> > introduce any scopes
>
> Aren't returns grouped near the end of function? Then validation checks would be implemented as forward jumps, which at least riscv interprets as unlikely by default.
>


August 28
On Wed, 28 Aug 2024 at 07:26, Walter Bright via Digitalmars-d < digitalmars-d@puremagic.com> wrote:

> On 8/26/2024 10:39 PM, Manu wrote:
> > Your suggestions could appear in almost every single at-least-warm
> function, and
> > it's not clear how they marry with eachother. We discussed 2 principle
> cases;
> > likely early return because of short-path or cached value, and unlikely
> early
> > return due to argument validation failure. Plenty of functions contain
> both
> > cases, and plenty of functions contain numerous such items.
> > Try and imagine how your suggestion scales when there are 4-5 conditions
> that
> > need to be tested on function entry, and they don't all receive the same
> hint. I
> > value readable and maintainable code...
>
> For reference, a real world example of your code?
>

Here's one that I just wrote a short while ago: https://gist.github.com/TurkeyMan/0e49da245cc0086f852ac18deed21a9c

This function can be very hot; called once for every byte in a byte stream
when sifting for a signal in a noisy transmission environment.
There are 4-5 guaranteed mispredictions in the nominal path in lieu of
hints...


August 29
On 8/28/2024 2:45 AM, Manu wrote:
> Here's one that I just wrote a short while ago:
> https://gist.github.com/TurkeyMan/0e49da245cc0086f852ac18deed21a9c 


```
if (data.length < 4) // unlikely
    return 0;
```

replace with:

```
if (data.length < 4)
    goto Lreturn0;
```
August 30
On Fri, 30 Aug 2024 at 04:32, Walter Bright via Digitalmars-d < digitalmars-d@puremagic.com> wrote:

> On 8/28/2024 2:45 AM, Manu wrote:
> > Here's one that I just wrote a short while ago: https://gist.github.com/TurkeyMan/0e49da245cc0086f852ac18deed21a9c
>
>
> ```
> if (data.length < 4) // unlikely
>      return 0;
> ```
>
> replace with:
>
> ```
> if (data.length < 4)
>      goto Lreturn0;
> ```
>

How is that any different? The branch prediction hasn't changed.


August 31
On Friday, 30 August 2024 at 02:54:28 UTC, Manu wrote:
> On Fri, 30 Aug 2024 at 04:32, Walter Bright via Digitalmars-d < digitalmars-d@puremagic.com> wrote:
>
>> On 8/28/2024 2:45 AM, Manu wrote:
>> > Here's one that I just wrote a short while ago: https://gist.github.com/TurkeyMan/0e49da245cc0086f852ac18deed21a9c
>>
>>
>> ```
>> if (data.length < 4) // unlikely
>>      return 0;
>> ```
>>
>> replace with:
>>
>> ```
>> if (data.length < 4)
>>      goto Lreturn0;
>> ```
>>
>
> How is that any different? The branch prediction hasn't changed.

I already asked this question.
He said a single break or goto is NOT considered the hot branch by the compiler.
But I don't like this, because it's an implementation detail that every compiler may implement or not, and it's not documented anywhere.
Maybe if the documentation would clearly state at a prominent point that a single break or goto has to be considered the cold path by the compiler, but a function call is to be considered the hot path (and all related queries about branch priorization link there), then I would consider this a solution. But is it likely this will happen?
August 31
On 8/31/2024 9:11 AM, Dom DiSc wrote:
> I already asked this question.
> He said a single break or goto is NOT considered the hot branch by the compiler.
> But I don't like this, because it's an implementation detail that every compiler may implement or not, and it's not documented anywhere.
> Maybe if the documentation would clearly state at a prominent point that a single break or goto has to be considered the cold path by the compiler, but a function call is to be considered the hot path (and all related queries about branch priorization link there), then I would consider this a solution. But is it likely this will happen?

It's the obvious consequence of laying out the code in the same order as the programmer laid it out. AFAIK every compiler does this by default.
August 31
On 8/31/2024 5:34 PM, Walter Bright wrote:
> It's the obvious consequence of laying out the code in the same order as the programmer laid it out. AFAIK every compiler does this by default.

Also the consequence of the "forward branch not taken" is assumed to be the hot one by the CPU, and the "backwards branch taken" is also assumed to be the hot one.
September 06

On Friday, 23 August 2024 at 07:33:53 UTC, Dom DiSc wrote:

>

On Friday, 23 August 2024 at 01:47:37 UTC, Manu wrote:

>

How can we add an attribute to the branch condition that the backend can take advantage of? I think it needs to be in the language spec...

I always arrange it so, that the if-path is the likely one, and the else path is the unlikely one.

As if anyone can remember that.

>

This also makes the code more readable,

Absolutely not. Early returns for unlikely-but-valid input like null pointers makes sense to me. Other than that, there’s if (...) throw ...;, but basically all optimizers recognize this as an unlikely path.

>

and it is always possible to do so.

Technically yes, but it makes some code harder to understand.

>

The compiler should optimize accordingly. No further indication should be necessary.

This is your style, and IMO it’s a bad style.