I've always wondered if any CPUs have tried to reduce the branch penalty by speculatively executing both ways at once in parallel. You'd have two of everything (two pipelines, two ALUs, two sets of registers, etc.) and when you hit a conditional branch, instead of guessing which way to go, you'd essentially fork. Obviously that requires a lot of extra transistors and you are doing computation that will be thrown away…
It's what happens and it gave us a really big issue a few years ago https://en.wikipedia.org/wiki/Spectre_(security_vulnerabilit...
The Weird Concept of Branchless Programming
41–50 of 92 posts
Re: The Weird Concept of Branchless Programming
#42I've always wondered if any CPUs have tried to reduce the branch penalty by speculatively executing both ways at once in parallel. You'd have two of everything (two pipelines, two ALUs, two sets of registers, etc.) and when you hit a conditional branch, instead of guessing which way to go, you'd essentially fork. Obviously that requires a lot of extra transistors and you are doing computation that will be thrown away…
Yes, this has been done for a while now, speculative execution + register renaming is how this happens. https://en.wikipedia.org/wiki/Register_renaming
Re: The Weird Concept of Branchless Programming
#43Re: The Weird Concept of Branchless Programming
#44I enjoyed reading the article, but I'm pretty thrown by the benchmarks and conclusion. All of the times are reported to a single digit of precision, but then the summary is claiming that one function shows an improvement while the other two are described as negligible. When all the numbers presented are "~5ms" or "~6ms", it doesn't leave me confident that small changes to the benchmarking might have substantially cha…
Yeah. When your timing results are a single digit multiple of your timing precision, that is a good indication you either need a longer test, or a more precise clock. At a 5ms baseline with millisecond precision, the smallest improvement you can measure is 20%. And you cannot distinguish a 20% speedup with a 20% slowdown that happened to get luck with clock ticks. For what it is worth, I ran the provided test code on…
https://gist.github.com/Stefan-JLU/3925c6a73836ce841860b55c8...
Re: The Weird Concept of Branchless Programming
#45I need something like this for a switch() command (technically a list of arbitrary functions). Sort of like up to N branches in one step. The idea is to take some number of inputs A, B, C, ... and conceptually perform all of the possible functions simultaneously, then keep the one that's desired and throw the rest away. For any arbitrary logic. Ideally using fewer operations than all of that, but that's optional. Dri…
https://godbolt.org/z/14h5djYe8
Although this looks branchless if you don't care about divide-by-zero. The ALU might not be too happy:
Re: The Weird Concept of Branchless Programming
#46I need something like this for a switch() command (technically a list of arbitrary functions). Sort of like up to N branches in one step. The idea is to take some number of inputs A, B, C, ... and conceptually perform all of the possible functions simultaneously, then keep the one that's desired and throw the rest away. For any arbitrary logic. Ideally using fewer operations than all of that, but that's optional. Dri…
vars[1] = var2 + var3;
vars[2] = var2 - var3;
...
vars[0] = 0;
var4 = vars[var1];Re: The Weird Concept of Branchless Programming
#47Re: The Weird Concept of Branchless Programming
#48Just so you know, the "return x abs_branch: mov eax, edi neg eax cmovs eax, edi ret on x64, and into abs_branch: srai a5,a0,31 xor a0,a5,a0 sub a0,a0,a5 ret on RISC-V if you use a C compiler with a half-decent codegen. And "branchy" clamp() translates into clamp: cmp edi, edx mov eax, esi cmovle edx, edi cmp edi, esi cmovge eax, edx ret Seriously, the automatic transformation between ?: and if-then-else (in both dire…
Re: The Weird Concept of Branchless Programming
#49I used to do stuff like this (ok, not half as smart), but stopped around 2013 or so, as the distinction between "implementation defined" behavior (ok) and "undefined" behavior (not ok) started to matter and bite. After thinking through this carefully, though, I do not see UB (except for signed overflow in a corner case): Step 1, bit shift. I understand that, until C++20, left shift of a signed int was UB. But this ri…
The UB on the add happens in cases where all incarnations of abs() would fail as well, because there simply isn't a correct return value.
Re: The Weird Concept of Branchless Programming
#50Just so you know, the "return x abs_branch: mov eax, edi neg eax cmovs eax, edi ret on x64, and into abs_branch: srai a5,a0,31 xor a0,a5,a0 sub a0,a0,a5 ret on RISC-V if you use a C compiler with a half-decent codegen. And "branchy" clamp() translates into clamp: cmp edi, edx mov eax, esi cmovle edx, edi cmp edi, esi cmovge eax, edx ret Seriously, the automatic transformation between ?: and if-then-else (in both dire…
> int partition_branchless(int* arr, int low, int high) {... for (int j = low; j That for loop is just a sugared while loop which is just a sugared cmp and jmp