News for hackers. Stuff that matters.
Re:Branch predictor: How many “if”s are too many? by dusted on Thursday May 06, 2021 @11:00AM (#27064227)
I'm wondering how you guys would optimize that code ?

My naive approach would be something like this:

const int numCountryIndicies = however many there are..;

const char* countries = "A1\0A2\0...";

return (cc < numCountryIndicies)?countries[cc*2]:"UNKNOWN";

Re:Branch predictor: How many “if”s are too many? by messe on Thursday May 06, 2021 @11:29AM (#27064720)
You have an off-by-one error. The strings are 3 bytes long.

I'd write something similar, more or less; Probably the following, not for optimization, but more as a matter of style:

    const char countries[][3] = {
        "A1",
        "A0",
       // [...]
    };

    // [...]

    int total_countries = (int) (sizeof(countries) / sizeof(countries[0]));
    return cc < total_countries ? countries[cc] : "UNKNOWN";
No need to hard code the length, and the cast is guaranteed to be within the bounds of an int on all platforms as long as you don't go over 2^16-1 countries.
Re:Branch predictor: How many “if”s are too many? by simias on Thursday May 06, 2021 @02:59PM (#27067686)
I think that's the best solution (the only potential optimization I can think of would be to add a padding byte after every country to force 32bit alignment which would make the offset computation faster on some architectures, although probably not on x86).

Stylistically-wise I think the best solution would be to write the array like:

    const char countries[][3] = {
        [0] = "A1",
        [1] = "A0",
    };
This way the codes are explicit when you read the code and it makes editing the array a little easier. Unfortunately gcc only warns if you set the same index twice with -Wextra, it remains silent with -Wall.
Re:Branch predictor: How many “if”s are too many? by messe on Thursday May 06, 2021 @03:36PM (#27068109)
> This way the codes are explicit when you read the code

Good call. It might have caught the off-by-one mistake I made (the codes start from 1 and not 0 in the blog post). Maybe even switch to using an enum as our index instead of an int.

Re:Branch predictor: How many “if”s are too many? by dusted on Thursday May 06, 2021 @12:47PM (#27065950)
Well caught! I have two off by one errors :D seems they start from 1 instead of 0, and I didn't account for the null byte :D your solution is nicer and easier to read :)
Re:Branch predictor: How many “if”s are too many? by Cerealkiller050 on Thursday May 06, 2021 @01:44PM (#27066742)
This jives with the overall point of the article of keep it simple and readable. The semi fancy indexing caused 2 errors and the upside is negligible after the compiler gets done with it.
Re:Branch predictor: How many “if”s are too many? by majke on Thursday May 06, 2021 @11:29AM (#27064729)
Modern freshest gcc 11 can optimize the if's nicely https://godbolt.org/z/771foExcG

  getCountry:
        mov     eax, OFFSET FLAT:.LC0
        cmp     edi, 258
        ja      .L1
        mov     edi, edi
        mov     rax, QWORD PTR CSWTCH.1[0+rdi*8]
  .L1:
        ret
Re:Branch predictor: How many “if”s are too many? by Denvercoder9 on Thursday May 06, 2021 @05:04PM (#27069025)
Anyone know what the purpose of the mov edi, edi instruction there is?

Edited to add: I understand that it's a NOP, but why would the compiler emit one here?

Re:Branch predictor: How many “if”s are too many? by Const-me on Thursday May 06, 2021 @06:18PM (#27069705)
That instruction clears upper 4 bytes of the rdi register. Note the next instruction uses rdi in the address.

edi register is the lower 4 bytes of rdi. Instructions which write these smaller pieces zero out the unused higher bytes of the destination registers. This helps with performance because eliminates data dependencies on the old values in these higher bytes.

Re:Branch predictor: How many “if”s are too many? by gaul on Friday May 07, 2021 @09:17PM (#27082714)
This is not a NOP; it explicitly clears the upper 32 bits of EDI since the compiler does not know that they are zero in this situation. If you change cc from an int to size_t (long on x86-64) the compiler will generate:

        mov     eax, OFFSET FLAT:.LC0
        cmp     rdi, 258
        ja      .L1
        mov     rax, QWORD PTR CSWTCH.1[0+rdi*8]
Note that in some cases the compiler can do this automatically via lifetime analysis but not in this freestanding example.
Re:Branch predictor: How many “if”s are too many? by JoeAltmaier on Thursday May 06, 2021 @05:09PM (#27069069)
It does nothing, so its a noop of sorts. I wonder if its a branch-delay tactic of some kind? Surely the algorithm is unchanged if it were removed.
Re:Branch predictor: How many “if”s are too many? by colejohnson66 on Thursday May 06, 2021 @05:11PM (#27069089)
It’s just a two byte NOP. IIRC, it’s Intel’s recommended form for one of that length. Windows uses it for hot patching,[0], but I can’t imagine that’s the reason here.

[0]: https://devblogs.microsoft.com/oldnewthing/20110921-00/?p=95...

Re:Branch predictor: How many “if”s are too many? by qayxc on Thursday May 06, 2021 @11:40AM (#27064924)
clang does the same - I tested it back to clang 7.0.

So clang did this for a long time it seems.

Re:Branch predictor: How many “if”s are too many? by fallingknife on Thursday May 06, 2021 @11:24AM (#27064636)
Does a ternary actually eliminate a logic branch? I always assumed it was just high level shorthand, and would be the same in assembly as writing out the if block.
Re:Branch predictor: How many “if”s are too many? by throwaway744678 on Thursday May 06, 2021 @11:28AM (#27064711)
It does not eliminate the conditional jump, it's just synctatic sugar.
Re:Branch predictor: How many “if”s are too many? by TonyTrapp on Thursday May 06, 2021 @12:04PM (#27065288)
And to make it more complicated, both "regular" ifs and ternaries may not generate a branch at all, e.g. by using the CMOV (conditional move) instruction on x86. This avoids a branch but can obviously not eliminate the data dependency between the condition and a later consumer of the result.
Re:Branch predictor: How many “if”s are too many? by PixelOfDeath on Thursday May 06, 2021 @11:45AM (#27065005)
Until after C++11, ternary was the only way to use "if then" in constexpr functions. So it has slightly more use from a C++ point of view.
Re:Branch predictor: How many “if”s are too many? by MaxBarraclough on Thursday May 06, 2021 @12:14PM (#27065438)
Following that line, it's never exactly been syntactic sugar. When initializing a const local, you can use the ternary operator on the right hand side of the assignment, but you can't get the same effect using if (short of writing a new function). Similarly, C++ lets you use the ternary operator for the left hand side of an assignment, (a ? b : c) = 42; although you could use an if for this pretty easily.
Re:Branch predictor: How many “if”s are too many? by andromeduck on Thursday May 06, 2021 @02:08PM (#27067077)
Wow I had no idea you could use it on the LHS. TIL.
Re:Branch predictor: How many “if”s are too many? by MaxBarraclough on Thursday May 06, 2021 @06:39PM (#27069833)
A TIL of my own: it seems not to be allowed in C.
Re:Branch predictor: How many “if”s are too many? by saagarjha on Friday May 07, 2021 @07:54AM (#27074895)
It works if you take the address of the b and c and then dereference. I assume this works without those in C++ because of references.
Re:Branch predictor: How many “if”s are too many? by gpderetta on Thursday May 06, 2021 @12:11PM (#27065386)
In a funny turn of events, in C++17 there is no ?: shorthand for 'constexpr if' .
Re:Branch predictor: How many “if”s are too many? by rantwasp on Thursday May 06, 2021 @11:03AM (#27064278)
it’s probably a switch on the index (or in this case you could actually have an array and use the index).

I don’t know my compilers that well but if I had to guess I would say there is a good chance this will be optimized away by the compiler.

Re:Branch predictor: How many “if”s are too many? by azalemeth on Friday May 07, 2021 @04:05AM (#27073535)
As pointed out above, gcc ≥11 optimises it to a switch / lookup table (https://godbolt.org/z/PxvGKqGrd).
Re:Branch predictor: How many “if”s are too many? by rantwasp on Friday May 07, 2021 @12:43PM (#27077879)
oh wow. this is really nice. was expecting some sort if gcc documentation or a blog post. got the real deal. thanks for the link
Re:Branch predictor: How many “if”s are too many? by lmilcin on Thursday May 06, 2021 @02:31PM (#27067360)
> I'm wondering how you guys would optimize that code ?

Run it on infinite multiverse, construct a mechanism to destroy the Universe every time branch predictor did not predict every single conditional correctly.

Re:Branch predictor: How many “if”s are too many? by Narishma on Thursday May 06, 2021 @06:13PM (#27069660)
It reaches out it reaches out it reaches out it reaches out— One hundred and thirteen times a second.
Re:Branch predictor: How many “if”s are too many? by dylan604 on Thursday May 06, 2021 @02:50PM (#27067572)
won't we need quantum computing for that first?
Re:Branch predictor: How many “if”s are too many? by lmilcin on Thursday May 06, 2021 @04:54PM (#27068934)
You don't need that.

The branch predictor can select a random branch, so it doesn't even need to actually predict anything. It should use quantum noise so that it has chance of selecting different branches in different copies of the universe. There is noting to compute, quantum or otherwise.

The bomb to destroy the universe will take care of all universes where it made wrong predictions, so that is where we should concentrate our development resources.

It has more utility than just branch prediction. Imagine the bomb going off automatically whenever there starts a war.

Any copy of the universe that starts a war is automatically eliminated and this guarantees that you, as an observer, will never observe any wars.

Re:Branch predictor: How many “if”s are too many? by teachingassist on Thursday May 06, 2021 @02:26PM (#27067301)
I immediately wanted to rewrite it as an array, yep, since the countries are already indexed.

And to minimize the risk of errors such as the "Anguila" error above.