> So, why not just cover that flaw by adding a carry/overflow flag.
Actually, why not just have a single generic 1-bit flag?
You could still have cmp + branch, but now you put the comparison type into the cmp. This gives you a larger branch range again.
A flag setting add/sub could also simply set that flag on carry.
cmov works, some form of ccmp also works.
> Well, cmov is absolutely possible without flags. You see such "select" instructions all the time on GPUs
Well, yes, because GPUs need 3r1w anyways, for fmadd, and because a dedicated cmov (blen/merge) is a lot more important in those workloads.
RVV also has "cmov" vmerge and full predication in general.
RISC-V wants to avoid needing to 3r1w on the integer side.
> But it does require three input registers. One for a control value, plus the two options. And RISC-V has a thing about not requiring three input registers.... Yeah, I'm not a fan of RISC-V.
Arm also tried to avoid 3R1W on the scalar integer side.
It's really only madd (on one or two ALUs) and some of the complex load/store ops, which are usually cracked.
My guess is that arm has 3R1W integer instructions, because they needed load/store pair for code density. That means they have to support renaming 3R1W integer instructions, so you may as well add integer madd.
I don't think they would've added 3r1w if it wasn't for the complex load/stores.
> One of the other major advantages of flags is it allowed for a cheap third input to certain instructions (like cmov, adc, ccmp), without requiring a full 3R1W register file.
Exactlty. Although I don't think the 3R1W instructions increase the register file size that much, because it grows linear with read ports and you usually don't need the full read bandwidth on very wide cores, as you can do port stealing. I think it's mostly about rename.
> But MIPS already proved it was possible, and showed all the downsides, it did not need to be tried a second time with RISC-V.
I think it's a fine way to design an ISA, however Zicond should've been on the base ISA.
> Out-of-order pipelines actually have a really elegant way of handling flags, they just store a copy of the flags register on every ROB entry.
And yet, flag writing instructions are usually half the throughput on regular ALU instructions, on modern wide ooo designs. [1, 2]
But I generally agree, there is a good way of handling them, it's hust unclear to me how expensive it is. It can't be that expensive, but apparently it is expensive enough, to not put a mask register write port on all integer execution units.
> Dart supports RISC-V as a target architecture for compilation, but I'm not really excited about figuring out how to map the wasm-SIMD-style primitives to RISC-V's RVV and so I don't really plan to look into it at all.
On the one hand, this will be quite straight forward, but on the other hand quite disappointing.
Afaik Dart has a 128-bit only SIMD abstraction (so not performance portable by default).
Since the base "V" extension mandates a mininum vector length of 128-bit, you can trivially make codegen work for all vector length, by simply setting vl to 128/elementwidth.
But as with x86, if your native hardware vector length is larger than 128-bit, you leave performance on the table.
> This is mostly because their approach to SIMD is so different, but also because I can't test it at all. Are there any RISC-V "machines"?
I'd recommend using qemu for initial testing.
Hardware wise, the cheapest option is the orange pi rv2, which has 8 SpacemiT X60 cores, which are in-order and support 256-bit RVV. The Zhihe A210 is also interesting, but way to expensive for what it is.
If you have a higher budget, I'd recommend the SpacemiT K3, which is the fist RISC-V SBC with RVA23 support. It is has 8 SpacemiT X100 4-wide out-of-order cores, with 256-bit RVV.
> No, not really. You can still jump into the middle a 32-bit instruction, and it's possible it can be reinterpreted as a valid 32/16-bit instruction. Remember when people complained about how "overlapped instructions"/"hidden instruction streams" on x64 enable even more ROPs/gadgets than meets the eye? Don't worry, RISC-V has those too!
Sure, it's a probabilistic thing. Whenever you see a 2-byte block starting with 0b11, you know there is an instruction start after those 2 bytes.
When I last looked at it, I got synchronize 99% of the time, when looking at a 8-byte block.
In one qemu trace I empirically got that only 626 out of 70479 8-byte blocks don't contain synchronizations.
This certainly seems like something you could exploit quite well, if you are doing things like 8+ wide decoding. (maybe have a fast path that safes one cycle of latency)
You can see the encoding limitation it in the design on SVE, which only has destructive operations, but MOVPRFX, which is a round about way of doing 64-bit instructions, without doing 64-bit instructions.
Not really, you would fetch fewer bytes with RVC [2, page 9], because the code density is better.
> I would be really surprised if the lower code density is worse than the improvement due to everything being nicely aligned.
This is very hard to quantify.
> Especially because Qualcomm had actual data that it isn't (if you add new instructions with the extra coding space you free up).
I've liked the back and forth slides bellow.
Though I want to bring up to things regrading the Qualcomm slides:
> [RVC] Performance benefit is modest
> • Best case: 2-3% speedup
I recently benchmark compiling programs with a rva23 clang build and clang compiled for rva23-without-C and got a 10% performance improvement from RVC on the SpacemiT X100.
I also have no idea how they got those numbers. (not that they are wildly implausible, it's just not transparent)
> Improving Android Code Size
In the last presentation they show how you can add a +-64M 32-bit long jump instruction to improve codesize in large binaries, like those in android.
There are two options when designing an ISA to achieve competitive code size, add variable length instructions or add more complex fixed-length instructions which require cracking (2W instructions). The other option is: maybe codesize don't matter?
For high performance implementations both decoding variable length instructions and decoding/cracking fixed-length instructions into uops, are rather analogous in terms of the work hardware needs to do.
However, I think the advantage of fixed-length instructions, is that you can do further tricks, like pre-decoding in Icache.
With RVC, you can also do pre-decoding, but now you need twice the amount of pre-decoding data, unless you find other tricks.
Still, in a reasonable variable-length ISA and fixed-length ISA, the variable-length one will get better code size.
There are also a lot of other things to consider, RVC is self synchronizing, cracking is challenging for decode, but also keeps the backend better fed, how more instruction starts impact branch predictors, instructions crossing cache-lines...
I benchmark compiling programs with a rva23 clang build and clang compiled for rva23-without-C and got a 10% performance improvement from RVC on the SpacemiT X100.
The X100 is a 4-wide out-of-order core and afaik doesn't do anything special for RVC, except for expanding the 16-bit to 32-bit instructions.
It's hard to quantify the real impact on a CPU design, but going the fixed-width route seems to enable more optimizations (not so much the decoding it self).
> Yes that's precisely the point of excluding it from the RVA profiles. It would mean that Linux distros don't compile code with C enabled, so chips are free to not support C and therefore can achieve higher performance (probably). And it opens 3/4 of the instruction encoding space for use by other things.
The debate was between 16/32/48/64-bit instructions vs naturally aligned 32-bit and 64-bit instructions + new more complex instructions that require cracking to regain code size (things like load/store pair).
> RISC-V defines a mechanism by which 48/64 bit instructions might be used, but currently none are actually defined
The long-instruction-SIG just started a few weeks ago, and they are working on defining 48/64-bit encodings for instructions that could be used in future RVA profiles (so with high perf implementations in mind). If you are knowledgeable about this stuff, please get involved, so they don't mess it up. (not "you" specifically, but in general)
I skimmed over the project a bit. It seems quite ambitious to aim to reimplement epub, considering that means supporting HTML, CSS, SVG and JavaScript.
Is there a ebook format that isn't just build arround the concept of a webbrowser?