←back to thread

386 points ingve | 2 comments | | HN request time: 0.416s | source
Show context
kookamamie ◴[] No.35738041[source]
Trusting the C++ compiler to emit a specific instruction for guaranteed performance - cute, but not realistic.
replies(1): >>35738060 #
vkazanov ◴[] No.35738060[source]
I don't think it is the instruction that makes the difference. Cmov is a branch either way.

Branches can be unpredictable and slow, no matter what instructions, (or tables, or whatever) are used to introduce the branch at question.

It is predictable nature of branching in this algo that makes the difference. Which makes me wonder...

EDIT: the cmov vs explicit branching story is a bit more complicated than just branch vs no branch.

replies(1): >>35738115 #
2102922286 ◴[] No.35738115[source]
Cmov doesn't branch. A branch refers specifically to the program counter ending up in more than one possible place after an instruction has executed. It is this behavior that mucks with the CPU state and slows everything down.

It's true that the cmov instruction uses the CPU flags register (which I'm sure the CPU designers at Intel hate), but that doesn't mean that it branches.

You can achieve the same effect as cmov by using bitwise operations and a subtraction, though it'd just be a few cycles slower--but it would be even more clear that it doesn't branch.

replies(4): >>35738178 #>>35738206 #>>35738285 #>>35742166 #
Paul-Craft ◴[] No.35742166[source]
Thank you for this comment! I was sitting here, metaphorically scratching my head, trying to figure out how the hell you can call this branchless when there's clearly an `if` in there:

        for (step /= 2; step != 0; step /= 2) {
        if (compare(begin[step], value))
            begin += step;
        }
Your comment, especially this part, made it click for me:

> You can achieve the same effect as cmov by using bitwise operations and a subtraction, though it'd just be a few cycles slower--but it would be even more clear that it doesn't branch.

BTW, I hate how the author doesn't use braces with this `if` statement. Many a production bug, including one in OSX, as I recall, have occurred because someone didn't want to type a couple extra characters.

replies(1): >>35744198 #
1. secondcoming ◴[] No.35744198[source]
Most topics I've read/viewed on branchless stuff seems to boil down to doing arithmetic with bools. So your code above can be thought of as:

   bool b = compare(begin[step], value);
   begin += (step * b);
replies(1): >>35744463 #
2. Paul-Craft ◴[] No.35744463[source]
Yeah, I got that. That was the part u/2102922286's comment made click for me. I guess I just don't do enough low level stuff for that to be something that automatically occurs to me.