←back to thread

386 points ingve | 1 comments | | HN request time: 1.064s | source
Show context
rowanG077 ◴[] No.35737974[source]
Nice algorithm. I don't agree that it is branchless however. Cmov is a branching instruction for sure. And it doesn't really matter whether a branch can be well predicted. The reason you mainly want branchless code is for security reasons where a timing sidechannel could reveal information. Calling this algorithm branchless devalues the term into something meaningless.

Edit: Everybody in the comments is focusing on performance. For performance sensitive code the point is not that it's branchless, the point is that it is fast, that some branchless code is faster than branching code is an implementation detail. During encryption the point is that it certain codepaths MUST be branchless.

replies(8): >>35738013 #>>35738026 #>>35738051 #>>35738053 #>>35738063 #>>35738216 #>>35738547 #>>35738591 #
Dwedit ◴[] No.35738547[source]
I just had it pointed out to me that CMOV can be simulated with subtraction and bitwise operators.

Specifically, subtraction, arithmetic shift right, and AND. `((A-B) ASR 31) AND C`. Your result is C if `A - B < 0`, and your result is 0 if `A - B >= 0`.

replies(1): >>35738958 #
spc476 ◴[] No.35738958[source]
In C, shifting signed integers is undefined behavior.
replies(1): >>35744227 #
compiler-guy ◴[] No.35744227[source]
Although it can bite you if you don’t know what you are doing, signed-integer shifting is not necessarily undefined behavior. Roughly, for positive signed integers, if the operation doesn’t overflow then the result is defined. For negative signed numbers, right shifts are implementation defined, but almost all modern systems define the result in the expected manner.

https://en.cppreference.com/w/cpp/language/operator_arithmet...

replies(1): >>35744838 #
1. kps ◴[] No.35744838[source]
Oh, it's too bad C2x doesn't seem to be following C++20 here, since they're apparently mandating two's complement.