flat assembler
Message board for the users of flat assembler.
Index
> Main > speculative execution |
| Author |
|
|
bitRAKE 16 Aug 2026, 21:03
(typical unreasonable for human):
- don't stack branches (one per decode byte set). - branch as last instruction in cache line. |
|||
|
|
sylware 17 Aug 2026, 01:09
You mean a sequence of direct branch instructions is not the right way to implement an in-code jump table?
Do NOPs count as last instructions? |
|||
|
|
bitRAKE 17 Aug 2026, 02:48
I think 1 or 2 branches in a row is okay - only seen performance hit on three in a row (in same decode).
All the references I see and testing show that NOPs are better at the start - speaking of loop alignment within cache lines. (Not talking about JMP.) _________________ ¯\(°_o)/¯ AI may [not] have aided with the above reply. |
|||
|
|
sylware 17 Aug 2026, 14:05
Is the performance loss of having "too many" branches in one cache line (querying the "BTB" starts to cost more) worth to read the resulting jump address from data memory and then to have only one branch instruction.
In other words, the over-querying of the "BTB" worth a data memory read instead (let's presume a L1 read). |
|||
|
|
bitRAKE 17 Aug 2026, 19:28
Obviously, at some fanout perfect hashes and jump/call tables are the answer. At the low end it isn't a win - it's something that's engineered around.
The decode size is typically 16 bytes. We can get 8 branches in 16 bytes, but the typical pattern is some change in flags between - now we're down to 4 branches or less. So, the 1/2 limitation isn't as heavy a constraint as it seems. Unless you're an assembly programmer intentionally setting many flags and stacking branches. |
|||
|
|
sylware 18 Aug 2026, 13:18
Baw, I may change those in-code jump tables to data jump address tables since, indeed, most of the time they have a "perfect hash" (I'll prefetch the cache lines). I'll see some '-O3' code on C switch instruction when we don't have a magnificient hash.
If I understood not too badly, BTB on modern microarchitectures seems more constraint to the cache line size than to the decode size (based on what I read and understood about that). I start to wonder if we should have CPU hints to declare that some branches should not be in the BTB (it seems microarchitecture designers say it's a very bad idea), namely all the time predicted using the static prediction rule of the microarchitecture (which is not the same on AMD and Intel/RISC-V). Why would it be a bad idea to reduce BTB pressure if we have semantic information on the usage of some branches... I guess they know better. I am trying to avoid to have to try to uncrypt that logic from the SOGs. EDIT: had a look at some -O3(x86_64 generic) C switch, basically no more that 4 "stacked" branches, then it builds a 'gigantic' intermediary data memory based jump table (several cache lines) to jump to other mini blocks with with max 4 "stacked" branches. It seems they are trying REALLY HARD to please the BTB. EDIT: It seems the "whatwg cartel" is still unable to completely gate the search and download of recent white papers on the BTB (good!), have some brain reading to do... |
|||
|
|
bitRAKE 23 Aug 2026, 21:20
Remember to follow compiler development - they are asking and answering the exact questions you're having ...
https://gcc.gnu.org/pipermail/gcc-patches/2026-August/728535.html (The only greater authority above the processor engineers is direct in situ testing.) |
|||
|
|
sylware 24 Aug 2026, 11:45
Yeah, BTB (Branch Target Buffer) alone is kind of misleading nowadays as the speculative silicon is now "large" and is mixing BTB, branch prediction, speculative code fetch and probably more.
I should rename the title. I was looking at generic x86-64 generated C switch code. Not even native [zen[45]] optimized... and it is already "scary". The current landscape (clang/llvm, gcc) of compilers is atrocious, apart from a few gems like cproc/qbe or tinycc. I suspect the choices of that squirting and bubbling diarrhea which is c++ from steering commitees of mainstream compilers is to force their devs to deal with its grotestquely and absurdely complex syntax. This is so sad, whatever the real reasons anyways. The worst being programers thinking hard that coding c++ makes them smart (I rather think abouth brain-washing or mental health issues before malicious dev lock-in). While I am thinking about it, that would not even be less worse with other computer languages of the same toxicity/complexity... Again, willing to pay 100 times the penalty to using a mainstream compiler NOT! That value is off the roof. All that said: their jump table is a sorta "bisection" of the switch values and some branch machine instruction "spacing". They do not fear data memory reads: certainly because a switch becomes, quickly, a source of misprediction penalties by its intrinsic nature, then L1 accesses are less worse in the end. |
|||
|
|
bitRAKE 24 Aug 2026, 20:20
I'm sure you get a sense for the things each compiler cannot do.
LLVM moves to a SSA IR representation early -- losing a lot of representational information. LLVM can't do negative loop counters - which instantly prunes a number of optimization strategies. LLVM IR doesn't have a pure unsigned type - oh, the irony. GCC uses a static machine model. So, it is modeling for a particular runtime state. No compiler I know of allows global registers - except their own internal uses. Compilers can't pass flags between functions. SSA IR's used in typical compilers mean complex addressing isn't possible -- it can usually reduce instructions or register usage. It gives me a headache reading the RISC dialect compilers use - so incredibly boring. |
|||
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2026, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.