One of the things that drives me nuts about RV is the plethora of Zextensions. And on top of those, manufacturers add on their own proprietary extensions. That is one of the selling points. But...
Interestingly, in the Olden Days, machines often had custom instructions. The pdp-1/D had a tad instruction for 2's complement addition (it was normally 1's complement machine), and there were also new pdp-1 instructions for timesharing.
For the IBM 1401, there were all sorts of add on 'features', e.g. the Multiply / Divide Feature (sped up * and / in HW), High-Low-Equal Compare feature, Advanced Programming (added Index Register, Subroutine Linkage), Move Record feature (allows right-to-left movement until hitting a Record Mark, useful for Tape), Expanded Print Edit Feature (float $ sign, automatic * insertion, etc), various memory sizes from 1,400 characters up to 16,000 characters. The point is that manufacturer-distributed software had to deal with having features (or not); and this was handled e.g. in the assembler by having a CTL card that listed (coded) the features, e.g. "CTL 31110" says this is a 12K machine, with Automatic Multiply / Divide, the High-Low-Equal Compare, the Move Record Feature, but NOT the Expanded Print Edit Feature -- that told the Macro Generator what it needed to know to properly expand macros for a specific HW configuration. (Certain Features did not require SW mods, e.g. the notorious "Print Overlap" feature that would speed up print operations by having a hardware buffer to hold the Print Line, so the CPU did not need to stall. The feature was notorious because the sub-rack of HW required to implement it connected into probably 75% of the machine's instruction decoder & execution units; when it failed, it was incredibly painful to find the fault(s)).
And, there have been Writeable Control Stores like, forever. It was a feature on the Burroughs B1700, where different control stores could be loaded on-the-fly depending if you were executing COBOL or FORTRAN or Pascal - the 'instruction set' would be optimized for running that particular language. The pdp-11 had some version of this, and CMU's custom C.MMP had something like this.
So, the desire for certain customers to have machines specifically honed to their use cases was normal. It has only been this brief period of homogenization of single-chip(ish) CPUs (8008, 8080, Z80, 8086... amd64 etc) that introduced new instructions in tranches.
The End-Users now get their custom instructions in other ways (e.g. PCIe and GPUs)
RISC-V is... fine. It satisfies my two requirements for an ISA as a hobby CPU designer, which are:
1. Supported in mainline LLVM and GCC.
2. I can implement it without lawyers sending me a love letter.
Everything else, I can fix in post. There are enough good ideas spread across the extensions that I can assemble a reasonably put-together, curated embedded ISA with competitive performance and code density that admits a simple implementation.
I think Dmitry's points are largely on-target, though I have filed my usual statutory complaint that every rant that includes a bitfield diagram for the RISC-V J format should accompany it with a similar diagram for the Arm T32 BL encoding.
> It satisfies my two requirements for an ISA as a hobby CPU designer...
You probably have some unstated requirements as well, such as available toolchains and "vetted well enough to actually be able to run code."
Risc-V now occupies the Schelling point for people who, for whatever reason (rent-seeking and security top the list) want to leave the x86 and Arm ecosystems.
I think the GP is talking about the Hazard3 [1] core. This is one of the CPU cores besides the ARM M33 instantiated on the RP2350 µC [2]. See this article from Luke Wren (Wren6991) back when the RP2350 came out [3].
What I find interesting is that RP2350 is designed as "one or the other", no way to use ARM and RISC-V concurrently, and has fuses that can kill ARM M33 cores outright.
Makes me wonder if an "ARM cores fused off, RISC-V only, no ARM fees" SKU is possible.
RISC-V is in many aspects just legally-distinct-MIPS, from the base instruction set all the way up to how certain extensions introduce kludges that are very reminiscent of later MIPS additions. While I do somewhat agree on the fact it was a huge missed opportunity to improve upon MIPS's technical flaws in order to realistically compete against the likes of ARMv8, we still have to keep in mind that the primary driving force behind RISC-V is and has always been fixing the legal flaws instead.
There is indeed plenty of value to be had from a standardized (if poorly) PlayStation-1-era instruction set you can safely implement in silicon with no risk of a zombie company husk coming after you, especially in the ASIC space where (as Dmitry himself recognized) anything is better than an 8051 core you need a copy of Keil C51 and a lot of patience to write code for. Even if you end up having to add custom extensions, it still is a much better starting point than coming up with your own bespoke ISA, building a toolchain around it and convincing potential customers that your proprietary architecture is worth the effort to deal with over another vendor's licensed Cortex-M cores with full GCC and LLVM support.
Yeah, very much legally distinct MIPS, at least as a starting point.
The biggest tell is the mnemonics. While RISC-V takes a bunch of ideas from other places, and cleans things up, it copies a lot of mnemonics straight from MIPS.
But it also copies a lot of other ideas from MIPS, like the absolute distain for flag registers.
The RISC-V specs insist that this is important for simplifying high performance designs, because a flag register is a single piece of shared state that instructions are constantly (and often inadvertently!) touching. This necessarily introduces hazards and serialization.
I don’t know enough about high performance microarchitecture design to evaluate that argument confidently, but it seems to make sense to me.
Inadvertent touching is fixable, ARM for example did it with the S bit (though on AArch64 it's slightly more complicated).
I regard it as a mistake of RISC-V. The flag register was invented for good reasons, and dropping it is a trade-off I personally do not think is worth the downside.
By the time you have an out-of-order core, there is already so much shared state you have to synchronise, and you have a bunch of complex mechanisms for dealing with it. Adding a flags register doesn't really add any more complexity, it's just a small bit of extra state attached to it.
And we already have the solution, it's register renaming. We are already renaming all the GPRs and FPRs, and we are probably also renaming part of fscr (because turns out, RISC-V does have flags for floating point operations), maybe a few other bits of state. So we just use the existing renaming mechanism to rename a bank of flags registers; That single logical shared flags register is actually backed with a bank of non-shared physical flags registers, neatly solving all concerns.
Sure, the renamed flags do take up a bit of die space. But IMO they don't add any extra design complexity, and shouldn't have any performance impact on maximum clock speed.
RISC-V isn't quite as disadvantaged by the lack of flags as some might suggest (and I wouldn’t say the lack of flags is RISC-V’s worst aspect), but there are a few sequences (add-with-carry, some conditional-moves, detecting overflow) where RISC-V is forced to burn an extra instruction or two to deal with the lack of flags, and IMO eliminating that would be worth the cost of slightly more die space.
Also, avoiding the need for dedicated compare-and-branch instructions would free up encoding space for other things (including larger range on branches)
You're thinking too high level and high performance/high power use -- think about minimal embedded controllers, no need to add the complexity of O3 exe, but there's still the possibility of getting to optimize the hazards and execution without the shared state.
Doing the deliberate choice of leaving flags out of the core and then using them in the fp ops ext will nudge designers towards "this is probably the point you should think about out-of-order execution"
If the spec was only arguing that avoiding flags allowed for simpler implementation of minimal in-order pipelines... I might actually agree with it.
But the argument in the spec explicitly uses the "added complexity to out-of-order microarchitectures" as a part of the justification for not having conditional move (and flags). It's the most commonly parroted part of the argument (see above) and the part of the argument I'm responding to.
I actually agree with much of the spec's argument. The cost of not having flags is pretty low, the MIPS approach does work pretty well, and it does simply things.
I'm just not sure it was the right trade off, and I strongly disagree with its attempt to use OoO cores as part of the justification.
Without knowing it, you're thinking at neither high nor low level. You've accepted at face value claims made by RISC-V architects about how to design an ISA for low level embedded controllers, but they weren't actual experts in that field. Instead, they were largely academics.
When you read their stuff, they're constantly overestimating the value of ultra-minimalist CPU designs in the modern context. In fact, they often show little understanding of the real impact of ISA design decisions on implementation complexity, so some of their decisions don't even make sense as minimalist decisions.
To expand on the low value of minimalism: even in trailing edge process nodes, if you're designing something on the scale of a simple single-issue in-order 32-bit RISC core targeting no particular frequency, gates are essentially free. The RISC-V guys are badly out of touch. If minimum gate count mattered as much as they think it does, there would still be a thriving market for 8-bit microcontrollers. Instead, they're steadily losing market share to 32-bitters, even in applications where an 8-bit µC would be more than enough. It's not the 1980s, you don't have to struggle to fit a featureful 32-bit core into a single die anymore, but they're hellbent on relitigating that era's debates.
> Adding a flags register doesn't really add any more complexity, it's just a small bit of extra state attached to it.
I agree in general, we do however see that the cost of flags isn't free by the fact that most modern Arm processors only support ADCS on half of the ALUs supporting ADD.
If it was free/negligible, you would see ADCS support on all ALUs.
Yeah... I more mean that it shouldn't add much design and verification complexity. You are mostly just reusing mechanisms you already need. Nor should it negatively impact FMAX. And I suspect the area cost is reasonably low (but not zero)
The lack of flags on those ALUs probably tells us more about the lengths CPU designers will go for reasonably small savings than it tells us about how much flags actually costs. And it's probably more of a "our metrics never gave us enough justification to even consider adding flags to the extra three ALUs" than "we considered it, but the cost was too high".
"it's impossible to prove a negative" is a simplification. A negation is just the oppositive of an affirmation. If the affirmation is "there is an element E of an infinite set S that satisfies property P", the negation would be "there is no E in S that satisfy P", which would make proving by enumeration require checking every element of an infinite set, which is impossible. But other forms of proof might be possible.
The set of US patents, however, are not infinite and, IIRC, is also public. That said, IP laws are a mess.
Someone might also file a new parent, then apply it against RISC-V. You'd think that wouldn't be allowed to happen, and maybe it isn't, but only an expensive lawsuit will prove it
Given the nature of the US legal system as based on common law, that applies beyond patents, and may affect ARM and x86 as well. In the end, the real, effective law is the one understood by judges, adjucated in court cases, built on precedents.
That being said, I don't expect someone filing a new patent after a RISC-V extension being published to last much longer beyond discovery in most cases, which should keep costs in lower end. Specially so in cases of bad faith.
If you build your architecture on ideas that are documented to be older than twenty years, it greatly reduces the risk that a patent holder comes from nowhere: even if they did have the patent, it would have expired.
How quickly does the industry move? Would there be any value in a 2006-era instruction set? How would you even start making sure you didn’t infringe on any patents that came after 2006?
The first version of RISC-V was released in 2010. It was based on work done at Berkeley in the 1980s (RISC versions one to four).
One reason that RISC-V has so many optional extensions is that you can trust the core is very likely to be patent-free (because everything in it is documented to be older than 20 years) and just evaluate the extensions you need.
If you iterate trough every concept RISC-V has, you might be able to prove it.
The RISC/MIPS concepts date back over 40 years. The base instruction set is intentionally designed with unencumbered, expired, or public-domain architectural concepts.
RICV-V microarchitectures and implementations are at much high risk of violating patents. Especially anything that is even slightly high performance. SiFive, Andes , and Alibaba’s T-Head are filing thousands of patents on microarchitectural optimizations and extensions. China's RISC-V patent-sharing alliances and other industry groups are building defensive patent cross-license around their RISC-V-related patents.
> it still is a much better starting point than coming up with your own bespoke ISA
5 years ago I would have agreed with this but now I'm not so sure. We live in an era where you can tell a robot "Here's some C code. Design a 64-bit ISA, write the Verilog to implement it in an FPGA, write a C compiler for it, and use it to compile the C code I showed you earlier."
And now your ISA and your compiler are part of your moat. I can just see the VCs salivating.
In the set of all possible working implementations, there are one or more that are novel enough to become a moat legally or otherwise. If everyone has the same power (number of tokens) then capability (experience and understanding) becomes the differentiator to “find” that moat first.
Designing a good 64-bit ISA, much better than RISC-V, is easy.
There are thousands of people who could design such an ISA in a couple of weeks, without any AI assistance.
The hard part, which has always been the moat of RISC-V, is writing all the required support software for a new ISA, i.e. all the utilities from binutils (assembler, static linker, ELF/DWARF utilities), compiler backends at least for gcc and llvm, debugger (at least a port for gdb server), dynamic linker and standard C library, possibly some parts of the standard libraries for other programming languages.
Previously this could have taken years and it is the only reason that has always justified the choice of RISC-V for minimum cost, despite how bad the ISA is.
If today the porting of all these software support applications to a new ISA could be accelerated with AI assistance from a couple of years to a couple of months, that would certainly enable the design and use of custom ISAs, and RISC-V would lose its appeal.
The effort to support architectures is now minimal with AI assistance. I made a hobby architecture (based on Intel, but with some changes; I was making an "alternate history" as if a few decisions in the past had been different) and it was pretty much trivial to spit out support not just in gcc and llvm, but I also, for fun, made WATCOM backends and a few other things.
With that said, RISC-V is a nice baseline for designing another architecture. Start with RISC-V, and go from there.
The main difficulty in support isn't actually making the changes (which is going to be largely defining various tables and other boilerplate, unless your ISA is really weird and does something unusual), it's in doing all of the politics necessary to get those changes committed upstream.
Maintining this type of long time fork is the kind of mind numbing, tedious thing LLMs are actually exceptionally good at. I did some backend work on Lean4 compiler and then they switched out parts of the codegen, it took Codex less than an hour to recover the feature set I had implemented but on the new backend.
It is the easy part. Four weeks is plenty of time.
That's why it's so bizarre that the RISC-V design is so awful.
The hard part is the software support side (though, as comments elsewhere in the thread point out, AI is pretty helpful there) and then those lovely pieces like specifying the precise behavior of interrupts.
If it had a snowball's chance in hell of going in to any kind of production anywhere, I'd have no problem spending the next month laying out an ISA. But, again, as this thread makes very, very clear: ISA really just doesn't matter.
> That's why it's so bizarre that the RISC-V design is so awful.
Not bizarre.
The design is a direct result of the biases of its initial designers, and its original intended use-case. And TBH, if you assess it by its original design criteria, it's actually pretty good.
It's just by the time RISC-V had escaped containment and was starting to become a general purpose open ISA, it was a little too late to start from the beginning and consider what the correct design criteria should even be.
Very true... but I can't help but note that basically every person I've ever met with significant experience with multiple architectures at this level, and not connected in some way to RISC-V, utterly hates the thing.
It looks an awful lot like something that was designed by a sizeable committee made up mostly of academics, most of whom won't have written ten lines of code in as many years. I don't actually know in this case, but I've had to sit and watch standards created in this manner, and Dmitry's description of the RISC-V mess matches their output fairly closely, a chaotic mess that includes every idea everyone on the standards committee has ever had, all made optional so no-one will vote against it when it comes to balloting.
How many people are working on this in your couple years example? Is that just one guy or a team of 20 or something else? Whats the average salary for the team *n this scenario?
I said "me" and "four weeks" because laying out an ISA is a pretty straightforward job for one person in one month.
The deliverable would be a (theoretically) complete specification PDF like RISC-V's.
I have little doubt that I or Adrian could do it, or plenty of others. It might not reach the quality of something like AArch64 with that level of resources, but it's not hard to beat RISC-V.
That's why I've never understood the point of RISC-V. Anyone can design a (reasonably OK) ISA. It's everything else that's the hard part. It's like announcing a new house, it's going to be pained Benjamin Moore Yellow Oxide and everything else is someone else's problem to sort out. Success! We've got a new house!
The only argument I've ever seen for RISC-V that's vaguely logical is that there's no licensing to Arm involved, but since I can get M0/M3 devices for a dollar or so with infinite tool and library support that's something that's totally irrelevant for most users. And if I don't mind going with Chinese suppliers there's no licensing to Arm being paid anyway.
Apart from being able to thumb your nose at Arm, I just can't see what the point of RISC-V is. Is that really all there is going for it?
> The only argument I've ever seen for RISC-V that's vaguely logical is that there's no licensing to Arm involved, but since I can get M0/M3 devices for a dollar or so with infinite tool and library support that's something that's totally irrelevant for most users.
How expensive is it to license the instruction set so you can expand it?
Dunno, I'm still saving up for the billion-dollar fab I'll need before I can think about licensing an instruction set.
As an aside, Espressif (or Xtensa if you want to split hairs) have been quietly doing a lot of what RISC-V is supposed to do for years now. I know they've also been fiddling with RV32's but all the real work is LX6/LX7. They're best-known for their use in ESP32s but they also crop up in an awful lot of industrial/commercial gear.
it still is a much better starting point than coming up with your own bespoke ISA, building a toolchain around it and convincing potential customers that your proprietary architecture is worth the effort to deal
There are lots of somewhat successful yet little-known Chinese companies with their own proprietary architectures and the toolchains to match, so I don't think it's that clear-cut. (That said, most if not all of them are somewhat MIPS/RISC-V-ish anyway...)
I do think 8051 is better when you don't need 32 or even 16 bits. Even 4-bit MCUs are still around in ultra-low-cost ultra-high-volume products, which is to say RISC-V is, as you said, just a different flavour of MIPS with very similar tradeoffs.
Google search turns up LoongArch (RISC), Shenwei (CUDA-like, HPC), UniCore (RISC). ESP32 is using Tensilica LX6/LX7 RISC base (RISC designed for custom hardware extensions).
C-Sky and Andes NDS32 were popular enough to be supported by both GCC and the Linux kernel, both switched to RISC-V. ESP32 switched to RISC_V for all new chips.
Interestingly Synopsys's ARC's latest version ARC-V is RISC-V.
I think all major FPGA vendors now offer fully supported RISC-V soft cores either alongside their older proprietary ISAs or as the latest upgrade. Several (e.g. Microchip and Gowin) have included real RISC-V cores inside FPGAs.
All states regulate, subsidize, or otherwise exert influence on companies acting in their territories. China is not unique or different in that regard. They have been forced to try somewhat harder, but that was really due to the actions of the US trying to restrict their access to free trade. Chine restrictions on buying western tech didn't come until far after NATO countries had placed similar restrictions on Chinese tech.
Yes, I'm serious. I think the overlap is an aesthetic problem rather than a practical one, given that:
* The profile used by "Big SoCs" already explicitly depends on F + D + C, implying ZcdZcf, so the newer Zce won't be implemented.
* The compressed float load/store opcodes repurposed for Zce are often unimplemented on embedded processors.
* The ELF file has an attribute section telling you the exact ISA string. If you're debugging an embedded system you probably depend on the ELF file anyway for DWARF info as you likely don't have frame pointers.
If you disagree then that's ok, I'm happy to be disagreed with, but please explain.
In x86 land, there are, as a practical matter, four ISAs: real/v8086 mode, 16-bit protected mode, 32-bit protected mode, and 64-bit “long” mode. Machine code targeting one of these will be executed correctly by the CPU as long as the CPU is in the right mode. (Really it’s messier — there are the CS.D, CS.L, and SS.B bits plus the control bits for v8086, protected and long mode, but this barely matters.)
Sure, this is messy. But, critically, on x86, these are all modes, and any CPU that supports them makes them detectable and supports them in the same way. If you run long mode code outside long mode, some opcodes will be interpreted as the wrong instruction. But you will not find multiple different CPUs that decode valid instructions differently. If I run your weird old x86 code, either it will run correctly or it will fault.
Oh, and all these modes are older than RISC-V. To the extent that there are lessons to be learned, RISC-V should have learned them.
The fact that you can apparently find two RISC-V CPUs that decode some ordinary user mode instructions based on published standards as entirely different operations is bizarre, to say the least. The fact that the relevant CPU features can’t even be enumerated in user mode just makes it worse.
(There are edge cases in x86. Some invalid opcodes have different lengths on different vendors’ CPUs. This is not a problem in practice because, one way or another, they fault. There was also a little glitch in the 64-bit design where some really really old x87 FPU code that uses exceptions cannot be corrected handled by a kernel on a modern CPU.)
> The fact that the relevant CPU features can’t even be enumerated in user mode just makes it worse.
User-mode feature detection is usually used to select paths for acceleration instructions, like SIMD or crypto. The overlapping RISC-V instructions don't fit in that category: they're compressed versions of basic functions, mostly used in epilogs/prologs, which would be unconditionally compiled in.
There are no overlapping encodings in the 32-bit encoding space and I'm really hoping it stays that way.
> To the extent that there are lessons to be learned, RISC-V should have learned them.
Yeah, I think I agree with this. Also I wish I had been there when Andrew Waterman was writing his master's thesis so I could ask him not to include Whetstone in his size benchmarks, so that we might have left that encoding space free and avoided this conversation :-)
> But you will not find multiple different CPUs that decode valid instructions differently. If I run your weird old x86 code, either it will run correctly or it will fault.
Oh, that's not completely true. Intel 64 and AMD64 are not identical and they certainly have encodings that behave differently. As an example: f3 41 90 is pause on Intel, but xchg r8d, eax on AMD (granted, this is not a canonical instruction encoding). 66 e9 xx xx yy yy is a unconditional jump to a 32-bit relative offset on Intel, but on AMD, the offset is 16-bit only (yy yy are the start of the next instruction). x86-64 is typically used to refer to the very large common subset, but this doesn't mean the implementations behave identically.
There are also some weird corner cases where CPUs aren't 100% backwards compatible, just backwards compatible enough for the software that matters.
For those less familiar with x86, the example instruction encodings that are interpreted differently on Intel and AMD are not base encodings, but instruction encodings modified with prefixes.
The x86 ISA includes a great number of bytes that are used as instruction prefixes, many of which are obsolete. The problem is that the effect of prefixes upon instructions has never been completely defined in any Intel or AMD documentation. The prefix effects have been documented for some instructions, but they were left unspecified for most other instructions.
This has lead to divergent implementations in the unspecified cases. Well-behaved compilers should not generate such undocumented combinations of instruction prefixes with base encodings.
> The problem is that the effect of prefixes upon instructions has never been completely defined in any Intel or AMD documentation.
In case of the jump example, the effects are documented by Intel and AMD and they still differ. Point of the GP was that all CPUs don't decode valid instructions differently, which is not fully accurate as shown by the examples; and some of these differences are also explicitly documented.
It's also not accurate that most prefixes are obsolete when most see regular use today (66 size override for 16-bit operations, f2/f3 for string operations, 66/f2/f3 mandatory prefix for many (e.g. SSE) instructions, 64/65 fs/gs override for thread-local storage access and per-thread kernel storage, f0 lock for atomic operations, 3e (again) for branch-taken hint, 4x REX prefix for r8-r15 and 64-bit operand size; one can argue that the 67 address-size override is useless, and only the 26, 2e, and 36 are ignored; I don't count VEX/EVEX/REX2 as prefixes but more as opcode escapes).
Some early 386 CPUs had XBTS/IBTS instructions (extract/insert bit string). They used 0F A6 and 0F A7 encodings.
Some early 486 CPUs had CMPXCHG encodings that reused the XBTS/IBTS encodings. That apparently screwed up some programs that tried to execute XBTS/IBTS to see if they were running on early (buggy) 386s so Intel moved CMPXCHG to different encodings (0F B0 and 0F B1).
0F A6 and 0F A7 are still left unused by Intel and AMD in their modern chips.
There's also the delightfully petty story about SYSENTER/SYSEXIT and SYSCALL/SYSRET for fast system calls. Intel came up with the first pair, AMD with the second. AMD of course had to support both and operating systems generally only supported Intel's pair.
Then AMD extended the x86 to 64 bits and of course required SYSCALL/SYSRET for 64-bit system calls (and did not support SYSENTER/SYSEXIT in 64-bit mode). Intel had to support AMD's instructions in 64-bit mode but decided to also support SYSENTER/SYSEXIT there (which I don't think any operating system has ever bothered to support).
To summarize: AMD supports both methods outside of 64-bit mode and only their own in 64-bit mode. Intel supports both methods in 64-bit mode and only their own in 32-bit mode. Or at least that's how it used to be. Maybe they've mellowed out by now.
Oh I remember SYSENTER/SYSEXIT, I think. I worked on CTOS, widely released by Burroughs/Unisys back then. CTOS used all the clever instructions. They performed badly. Later I learned from an Intel customer consultant on porting code, that we were the only ones who ever embraced fancy things like task gates etc. Everybody else just continued using regular push/pop and simple traps. Because they ran faster.
Yes, but x86 had a goal of running every old piece of code on the new thing. That’s not true with RISC-V. Whereas x86 accreted more and more features, RISC-V solves this with profiles that are not guaranteed to be compatible with each other. RISC-V doesn’t even support running 32-bit code on 64-bit processors without a recompile. In a sense, 32-bit RISC-V is a vaguely similar but incompatible ISA to 64-bit RISC-V. That would be a train wreck if there weren’t profiles to specify a group of features that must be there (and some others that might be optional, with a register to flag whether they are or not). The expectation is that profiles act a lot more like the x86 ISA, accreting features while preserving backward compatibility. It took me a while to realize this, too, and I remember several WTF episodes while reading through the specs. And of course profiles go beyond the ISA and specify system level arch as well (like the “PC architecture” did for Windows and Linux). You can certainly argue that it should have been done differently, but it’s not completely crazy given that there is not legacy RISC-V code needing to be run on newer systems for the most part. That won’t be true forever, and so profiles help manage that.
There is a lot to unpack, hence my reaction. Instead of a straight compressed instruction format supported (or not supported) everywhere, we get an alphabet soup of options. C -> "ZcfZcdZca" just by itself is insanity. But the actual technical change is a problem too. Now I can't make vendor-independent RISC-V code, since apparently they all support different compressed instruction sets.
I represented my company as a founding member of the RISC-V foundation. I now shake my head at what it has become and hope I never have to write code for a RISC-V system again. Every time I check in it seems like some new insanity has manifest itself.
Separating the float load/stores from the rest of the compressed ISA is insanity? Why?
> Now I can't make vendor-independent RISC-V code
I think this is what RVA23 is for. Any system running shrinkwrapped binaries is going to have vanilla RVC.
I agree there is some insane stuff going on in RISC-V. Like when the double-trap spec was in public review I popped my head in to say "hi, this seems to break all existing code that uses nested interrupts because the condition is overly broad" and the spec maintainer said words to the effect of "yes, it's supposed to do that."
This is not that weird, though? Float load/store should never really have been included in the C extension, but we can't revise the C extension. So, define an extension for "C: the good parts", aka Zca, and separate extensions for float load/store (two of them because F and D are separate). Ideally we wouldn't have made the mistake in the first place, but what would have been a better way to redact it?
Not redacting it would have been better. Either live with it, or you explicitly create a new incompatible ISA. What happened is the worst of both options.
You thought RISC-V chips were compatible with each other beyond the basics? They're not. RISC-V is only a starting point for designing the ISA your chip will actually implement. Don't get me wrong - it's still beneficial that simple code works on many chips.
HP wrote a JIT to migrate old applications to their new hardware. So did Apple, twice. I don't know if IBM were the first but they've done it a few times as well for their mainframe hardware.
In HP's case, they tried running their JIT to translate from architecture B to architecture B and ended up with better performance than running it directly.
100% agree. Is it ideal? Nah. Can you launch successful products with it with only a moderate amount of headache? Yep!
Heart of our system that powers a household name devices is a RISC-V multi-hart SoC. It does quite a bit - a little bit of compute, a little bit of DSP. Definitely not the best fit, but cheap and works well enough. The buggest gap for us was the lack of the decent debugging featurea like ARM's Data Watchpoint Traces - but maybe there is an extension for that already?
Yeah, so was 8051 and it sucked too :-). I appreciated having this rant all in one place. Ranting against bad architecture is always cathartic and absolutely useless since the people who built and now champion the bad architecture are invested so one's rant simply irritates them. And like the parent comment here, I too find RISC-V "useful" in that it has sufficient tooling to make most everything foundational 'out of the box' rather than me having to build it.
Perhaps the most interesting thing is that RISC-V shows just how ISA agnostic people are, as long as you have cross compilation with the gcc suite and an open source way to program and debug things. Before RISC-V, working on a bespoke ISA and computer architecture was never going to "go" anywhere except perhaps into a paper or conference talk. Now there is evidence of a non-zero chance of it going mainstream. :-)
> Perhaps the most interesting thing is that RISC-V shows just how ISA agnostic people are
To the extent that Raspberry Pi shipped a microcontroller that can literally be either RISC-V or ARM (indeed, one of each at the same time I think?)
RISC-V, it seems to me, lives in that cognitive space occupied by things like: open source, open weights, C, HTML, ethernet, Greggs sausage rolls and VHS.
Far from optimal, obviously flawed, and could change human society for the better. Ubiquity is inevitable.
What’s far from optimal about open source? Open source seems like a window into another universe, which is just lightly better than ours: people just working on problems and sharing solutions, because humans are basically good social creatures that enjoy solving problems. To the extent to which there are issues like the difficulty of funding open source projects: our society is wrong, not open source.
> Perhaps the most interesting thing is that RISC-V shows just how ISA agnostic people are
Of course! Most people in the computing world work way higher up the ladder of abstraction. I suspect a small minority of working software engineers know what an ISA even is.
I did some contract work in web development for a time. It is staggering how few people understand how the javascript they write gets executed on the machine. People don't understand pointers, or virtual machines, or in many cases how JS bundlers work, despite using them daily.
In some ways, this is a sign that our abstraction layers have been a great success! People can program for the virtual javascript machine, without needing to understand how the actual machine works, or how it emulates javascript. Is this the future we wanted? I'm not sure. But it's here.
Definitely. I’m a weird software guy that got a hardware degree in college so that I could understand all the low level stuff. I remember there was a joint project with the hardware (ECE) and software (CS) students to build a simple computer with bit slice and microcode and program it to do something (I forget what). I remember the software students being bewildered that there was no division instruction in these systems (because who needs that when you have shifts and add/subtract). Nowadays, with so much stuff running in browsers, the average software engineer has no clue what the hardware is doing.
Nobody wants to cross compile a full linux OS though just for their project. I assume most are using debian multiarch (as they do for arm), and that does mandate a common RISC-V ISA subset. So presumably this will drive further standardization
It originally had a range of 4 MiB, and they extended it to 16 MiB in a later ISA revision. The bits with the XORs were originally constant-1 and they wanted to keep backward compatibility, so bits J1 and J2 are interpreted as "if this bit is clear, toggle this position in the leading sign bits".
There is very cool history as to why. In armv5 the BL was two separate instructions. You could take an interrupt in between. And it was documented what each did. Veeery cool. Then they wanted more range. And now that they redefined the two halves as one instruction that could not be in halves, they also redefined a few bits that were always 1 before, to allow the second half of the instruction to be recognized right without a “previous instruction was first half of BL” flag somewhere that would need to be context switched and all that.
My disagreement with the article is mostly the following:
RISC-V is not an ISA, but an ISA generation framework.
If RISC-V would've standardized aarch64 1-to-1, the end result would've still been a huge extension mess, because a lot of people (RVI member) have different requirements and a very happy to build their own subsets, which would then be upstreamed because multiple vendors want the same subsets and compatibility between them. Obviously it would've been better, similar to if RISC-V spawned with RVA23 done, but development takes time and RISC-V International started, because people where already using RISC-V.
RISC-V also is the most DOSed ISA, with people proposing crazy stuff. Just the other day somebody proposed an instruction that would do up to 2^30 16-bit comparisons in one instruction at the largest VLEN. Because they wanted to improve their string processing usecase.
---
In my experience RVA23 matches aarch64 and x86 in uop count (without fusion), code density is better, instruction count is slightly higher. The biggest impact on the instruction count advantage of aarch64 over RVA23 is a single instruction, load-pair, which gets cracked at decode in every high-performance implementation, because it writes to to registers.
The Arm approach to code density is using multiple writeback instructions that have to be cracked and the RISC-V one is RVC. Both prohibit simple linear scaling of parallel decoding, so code density seems to have mattered to Arm enough to make the tradeoff worth it.
The decoder decodes them into two or more internal instructions (uops).
Take for example a post increment load, which does a=mem[b++], notice how this writes to two registers.
Handeling two writes (up to 4) would explode the stage after decode (rename).
So high performance arm implementations generate two uops for this.
But since the number of decoders is fixed and the number of rename slots as well, you now have alnost the same problem as in RISC-V with compressed instructions: the nth input to the rename stage can come from a variaty of outputs of the decode stage, so you need a large shuffle network, and propagate the uop counts from start to end.
Cracking is a lot cheaper, if you can do it later in the pipeline. E.g. the cheapest is if you can simply "replay" the instruction. That is, instead of removing the entry from the issue queue, when it starts executing, you decrement a counter and keep the entry to do something else next.
But as I mentioned that doesn't really work with multiple write back.
> What does a cheap microcontroller core need? Let's inspect what they are used for. Typical use cases are to interface with and quickly reconfigure hardware blocks in a larger chip, eg in an MP3 player, an SD card, or a USB stick. The hard work is done by custom IP and the CPU core is just there to occasionally prod a register or configure something.
This is not the only reason to use a microcontroller or 75% of microcontroller vendor (e.g. STM) offerings would have no customers. Not everyone has custom IP that does all the work either, that’s actually fairly rare. It’s odd to pigeonhole microcontrollers like this just to go on a fairly lengthy rant about interrupt latency as if that somehow makes RISC-V unsuitable to what is an incredibly diverse application space. Maybe the rest of their post has better arguments, but I’m not impressed enough by the first one to keep reading.
This is a "microcontroller core", not a "microcontroller".
We're talking "deep embedded" applications - where an ASIC is designed for a very specific purpose, and that design just so happens to call for a programmable CPU core to be included in it.
This is the kind of design that lives in your keyboard, your mouse, your USB stick, your USB hub, your HDD, your SSD, your eMMC chip, your memory card and more. Remember: you're never more than 3 meters away from an 8051 core.
I do agree that most of this piece is nitpicking - poking at ultra low level things that are largely irrelevant to the tried and true "deep embedded" exercise of Just Ship It.
No one really gives a shit if an operation takes one instructions or two, or which instruction sets are consistently present in different cores. What "deep embedded" people give a shit about is not having to work with ancient 8051 tooling and 8 bit ALUs and memory banked 64kb spaces while writing code for the one core they happen to actually have. And RISC-V got that. The piece actually agrees with that sentiment.
By volume, I would expect the majority of microcontroller silicon shipped to be these kinds of deeply embedded cores. They even show up in chips called “microcontrollers.”
EDIT: Leaving that Å in. For some reason, iOS on iPad is obsessed with autocorrecting "A" to "Å" even when using the English keyboard. It's driving me nuts.
Yes, it's one of the options there. But I'm not doing that, I'm just pressing the A key and it automatically gets transformed to Å once I hit space around 50% of the time.
Yes but autocorrect is on the whole useful, I'm a bit sloppy when I type on glass and it's probably correct a little bit more than it's wrong.
Actually I'm not sure if that's even true anymore. It constantly "corrects" "its" into "it's" (it even did it just now) in situations where "its" is appropriate. It corrected the "on" in "type on glass" earlier to "in". And half of my "A" gets turned into "Å" (it just happened again and I had to go back and fix it). Maybe it has gotten to a point where it's wrong more than it's right.
You can add a correction going the other way and it may fix the problem (it did for me for a similar problem, anyway) in Settings -> General -> Keyboard -> Text Replacement. Try replacing “Å” with “A”, or “A” with “A”, and see if that helps.
Not really. Before RISC-V, the low end was held firmly by 8051, and at the high end, it was a fight between Xtensa, ARC, M0, and "others", be that custom ISAs or something like legally distinct MIPS.
And I suspect it’s accelerating quickly. This whole space is hyper cost-competitive and pennies matter, so being able to design whatever you want without having to talk to lawyers or pay anyone anything is a huge win and matters far more than whether something takes 1 instruction or 2.
I thought so, too. The Cortex M0+ is quite nice. RPi Pico RP2040 (original) https://pip-assets.raspberrypi.com/categories/610-raspberry-... uses them, and with the RPi on-chip math help (clever stuff) it's quite the joy for your toaster or microwave oven project. RV32EC is 'ok' but the weirdly reduced register set to save a few dozen transistors seems like out-of-control hardware guys without any software supervision - the bane of this industry.
Now-a-days, I actively avoid RVxxx Zwhatever because those guys had their chance and seemed to have learned nothing from the IBM 360: SOFTWARE is what ultimately matters, as long as you don't have ridiculously expensive chips, keep the ABI consistent!
And, ARM learned from M0 and quickly came out with the M0+ --- which SHOULD be the 8051 killer (no offense to my friend John Wharton (RIP), 8051 designer https://en.wikipedia.org/wiki/John_Harrison_Wharton): M0+ is a lower-power, more efficient redesign of M0, 2-stage pipeline, Harvard bus, and optional features (MPU, MTB, fast I/O) that M0 lacks. The RPi Pico has all of these optional features except the MTB (Micro Trace Buffer), but does have 4 breakpoints / 2 watchpoints per core, 8 memory regions, single-cycle I/O port access, 30% less power than M0, and 12% less die area, 32x32 single-cycle multiply, Thumb-2: "32‑bit Performance at 8‑bit Cost" https://documentation-service.arm.com/static/60411750ee93794...
If RISC-V was good enough for AMD to use it in their controller for their GPUs and it became cheaper than ARM, and NVIDIA is using it in many places, it was better to build upon than getting a change in ARM/x86 licensed and approved by Jim Keller, it's good enough.
It turns out that the cost of waiting years for an ISA change is more costly than fixing whatever problems it has.
I think I get it. I've tried microblaze-v for a while now. And just look at their interrupt handler. https://github.com/Xilinx/embeddedsw/blob/master/lib/bsp/sta... . With the FPU enabled at compile time, that's > 128 memory ops per interrupt. That's insane, especially without an NVIC and chaining and all that. My latency was astronomical, and my maximum interrupt frequency was pitiful. Ended up doing the work (sw and hardware options) to get it to operate more like arm-m, but arm-m doesn't need that work to be done. NVIC is always NVIC, and NVIC is good
Yeah, this is a bug. They should only be saving the FP state if it's dirty.
Also this is one of the reasons I think Zfinx is a better option for embedded (i.e., the standard FP instructions operate on x registers instead of f registers): 31 registers is plenty to hold a mixture of integer and floating-point values, and you avoid the worst-case context save penalty.
Not a bug, just not optimized. Because I think there's a csr to read it the fpu is dirty but... That requires csr extension. It would also increase jitter, which in some cases is more important. At best it should be still there as an option, but also optionally improved
Fair enough. It's a performance issue but not a functional correctness issue.
> Because I think there's a csr to read it the fpu is dirty but... That requires csr extension
Yes, and they already unconditionally read that CSR :-)
The "CSR extension" is an almost 100% theoretical concern. It was the spec authors being defensive in case the privileged ISA was so flawed they had to throw it out in future, while keeping the base ISA. I don't see that happening at this point.
The only exception is deeply embedded cores that drop even basic IRQ and exception support. These are always going to exist and I think they're a sufficiently separate class of processor that they don't really factor into the compatibility equation, because such processors usually only run one program in their entire lives.
You know what, you're right. I was thinking of the timer option. I don't think you can turn off the csr functions on that core. But I've gotten into trouble turning off the timer
No. That's also partially in the article. But even in ones that do, usually it's a subset. In arm-m, some registers get stacked on interrupt (basically the caller saved ones in the ABI so any regular functio is automatically IRQ compatible). In this implementation, 64 registers do. Very different from I think it's r0-r3, lr, and pc. Some architectures bank them, so as long as you don't nest or call functions you can just use the interrupt bank.
RV actually allows for that. But not dictating that registers get pushed to the stack, flexibility in how you manage them opens up. So for RV, and some other architectures, you have to mark the function an IRQ and the compiler will know how to figure that out.
Another gotcha is that for AXI and other burst interfaces, the hardware being able to say "I'm going to send you X words" is dramatically better for latency than each one being a single transaction. So if your stack is in a location that requires multi-cycle memory access times, this balloons in timing cost.
Sadly this is a very hard topic to condense into a few sentences. Maybe if I wrote an article on it with graphics it would help. Unsure
the significance and allure of risc-v, the reason china is investing heavily in it right now, has little to do with the technical details of how it works under the hood, it's the fact that it is an open standard not encumbered by intellectual property law. even if it isn't technically the best general-purpose processor architecture, it sets an important precedent by proving that it is possible to develop an open public architecture that the world can use to build computing devices without being extorted by a multinational corporation charging licensing fees or a geopolitical superpower enacting tariffs and sanctions.
> it's the fact that it is an open standard not encumbered by intellectual property law.
There are actually many of those. But Risc-V has become, through effective marketing, the Schelling point for anybody who wants to avoid the x86 and Arm ecosystems, both for the rent-seeking behaviors you mention, and also, in some instances, for security reasons.
And, as others have mentioned, the ISA doesn't really matter. As long as it's agreed upon, then the CPU vendors can optimize on one side, and the compiler writers on the other side.
Sure, Risc-V has its warts, but you can certainly say the same about all the rest.
The ISA not mattering I think isn't as true when you account cost e.g. in a huge OOO cpu all the fusions and so on are afaict fairly doable but if you are on a cheaper / worse CPU all those extra bytes in the instruction stream do add up.
The RISC-V fusion arguments from back in ~2018 didn't really pan out. A lot of those fusion opportunities are just instructions now. slli + add? Zba (sh*add). slli + srli? Zbb (zext.*). slli + srai? Believe it or not, also Zbb (sext.*).
Look at that pair of RVC instructions you used instead of a single 32-bit opcode. They are:
* Taking up valuable compressed instruction space; each compressed codepoint has an opportunity cost of 64k uncompressed ones.
* Limited in which registers they can use (usually x8..x15).
* Often clobber their input operand instead of giving a free move.
Also consider that the frequency data that drove the RVC compression decisions was driven by the lack of architecturally fused instructions like sh*add, so any arguments you derive from that data are circular. An instruction can be a good uarch fusion target because it's compressed, and a good compression target because you didn't fuse it in the architecture.
I think designing for uarch fusion in your ISA is coming at it from the wrong end. Fusion is something uarch designers do to make up for shortcomings in the ISA.
The combined comparison-branch instructions of RISC-V are its only good feature in terms of instruction encoding design.
This allows a significant code size reduction in comparison with ARM Aarch64, but unfortunately for RISC-V this advantage is frequently not enough to compensate its other defects, especially when reliable code is desired, i.e. where overflow detection is necessary.
Despite that from this point of view ARM Aarch64 is weaker, that is not an intrinsic problem. Aarch64 has an unused block of encodings inside the block used for branch instructions. I have verified that in the currently unused block it is possible to encode not only compare-and-branch instructions covering all the conditions that exist in the RISC-V ISA, but also additional conditions that are missing in RISC-V, where their absence is a problem, like testing for overflow.
I do not know why nobody at Arm had thought to make this extension yet, but it would be very easy to eliminate the only advantage that RISC-V has over Aarch64.
> I do not know why nobody at Arm had thought to make this extension yet, but it would be very easy to eliminate the only advantage that RISC-V has over Aarch64.
Nope. Again, the primary advantage that RISC-V has over Aarch64 is that it is the agreed-upon open specification.
Sorry, haven't been following along, but sounds to me that the argument was a valid one seeing how it made the designers add new instructions.
Not sure if there's an impact caused by the late addition as opposed to always having them, but considering this is a fairly core thing what a program does, not sure what degree of fragmentation this causes on the level of compilers and hardware.
x86 effectively killed innovation in the SIMD space by making instruction set support so fragmented, that people had to target the decade-old lowest denominator.
Performance is subject to debate and quality of implementation and whether such implementations will ever be financed and made ...
But *code size* is a demonstrable fact.
RISC-V has by far the most compact code of any popular 64 bit ISA, and that was true even of RV64GC. The gap has only widened with RVA23.
Just load up your favourite OS (e.g. Ubuntu 26.04) for various ISAs in Docker and compare the `text` size of various binaries, individually or in aggregate.
In 32 bit ARMv7-M / ARMv7-A had a small code size lead over RV32IMAC, but this is reversed in modern RISC-V e.g. if you look at RISC-V Hazard3 vs Arm Cortex-M33 in the RP2350 (Raspberry Pi Pico 2) where you can trivially change one option setting in your project and recompile and test.
The only exception is that the M33 has a single-precision FPU, which neither the Hazard3 nor the Cortex-M0+ in the RP2040 have.
No, RISC-V code is much more compact than Amd64. This is easily demonstrated on any real application, such as those in your favourite Linux distribution.
All the claims of the RISC-V fans that I have seen in the past compared the compressed variant of RISC-V with the uncompressed variants of the other ISAs.
Most other ISAs, like ARM, POWER and MIPS, also have compressed variants and if RISC-V were compared with those, it would lose.
Moreover, if you use safe compilation options with RISC-V, the code size explodes in comparison with any other ISA, because I am not aware of any other ISA introduced after 1974 that lacks hardware overflow detection, which multiplies by 3 or more the number of arithmetic instructions required for any computation.
This is a new claim that I see now, that RISC-V can be more compact than Cortex-M33 (i.e. where both use a compressed encoding), which I find unbelievable, because if I assembly by hand almost any function that is not too simple I can make it shorter on Cortex-M33 than on RISC-V and I doubt that the current compilers are so bad that they generate much worse code.
RISC-V is shorter on any code that has a lot of branches and negligible computations, but for anything more complex, with many computations and complex data structures, it loses.
I want to try looking at codesize for -Os builds with the different ISAs including the compressed variants you mentioned.
As well as dynamic icount with overflow checking.
Do you have any specific project in mind that I could use for testing?
I keep seeing comments here saying that a)compressed instruction are awful for pipeline decode, so they aren't used in any ISA on fast speed and b)risc-v loses in code size if you compare against compressed instructions
I don't understand how the two viewpoints fit together
> I don't understand how the two viewpoints fit together
Well, they don't and they do. Linux runs on everything from an $8 generic IP camera to the world's fastest supercomputers.
RISC-V is attempting to achieve the same feat in hardware, so there will be many implementations at many price points.
As with any of the T-shirts that list 3 things and say "Pick two" it's always difficult to reduce cost, increase speed, and decrease code size.
But...
You can pick two.
So if you don't mind spending the money for things like fancy micro-op caches, you don't care about the compressed decode, and you can still make it run like a bat out of hell with compressed instructions.
Or if you don't mind lower performance, you don't worry about fusing operations, and the pipeline implications aren't so bad, so you can still make something cheap that works with compressed instructions.
It's only when you're trying to pick all 3 (compressed instructions, high instruction throughput, and low cost) that the difficulty of decompressing the instructions becomes problematic.
Or look at it this way. x86 decode is infinitely more complicated than RISC-V decode, and still occupies maybe 2% of the die area.
x86 is basically one big cabinet of horrors, but people seem to put up with it because it's "the standard." Then why not with RISC-V? Which is much if not infinitely better.
> […] then the CPU vendors can optimize on one side […]
I find the statement ironic and somewhat amusing (or bemusing – depending on the perspective) for reasons entirely unrelated to CPU's and/or RISC-V.
I keep hearing the phrase «we shall leave that to the vendors» every now and then. Only a few days ago, whilst attending a working-group session on an emerging data exchange standard, precisely the very much same argument was bluntly stated: «We do not particularly care how complex the specification becomes because the vendors will implement it. We shall leave it to them».
The issue is that «the vendors» are not a single mythical intelligence or force possessed of infinite technical wisdom, unlimited, cosmic scale engineering resources and an relentless desire to right the wrongs.
They are businesses. They have narrow commercial objectives, conflicting priorities, disparities in the engineering talent and resourcing and, quite properly, incentives to advance their own products – you are right, to compete with other vendors. Where an opportunity appears to increase market share, lock customers in, differentiate their platforms and products or shift implementation burden elsewhere, one should expect them to notice it. It is not an accusation, it is merely an acknowledgement that vendors tend to behave like vendors.
So with «the vendors will do X», at best, we may hope that vendors will deliver an interpretation of the specification – to a degree, provided that doing so aligns sufficiently well with their commercial interests. An equally plausible outcome is that they will not – or that they will each implement mutually incompatible interpretations whilst proclaiming full compliance.
What you find may or may not match reality. In this instance, I don't believe it does.
> We do not particularly care how complex the specification becomes because the vendors will implement it. We shall leave it to them.
This, of course, is a silly argument. Yet, it is completely orthogonal to the one I was making, and is 180 degrees away from the complaints leveled at Risc-V which are that it is an overly simplistic, nay childish, specification, written in crayon by kindergartners.
> The issue is that «the vendors» are not a single mythical intelligence or force possessed of infinite technical wisdom, unlimited, cosmic scale engineering resources and an relentless desire to right the wrongs.
I find this statement accurate, yet condescending. Who the fuck thinks that they are? Claiming that this is an "issue" with my statement appears to be a reductive argument that I have not thought it through. To be blunt, this statement reveals a hell of a lot more about your ignorance on this issue than mine.
> It is not an accusation, it is merely an acknowledgement that vendors tend to behave like vendors.
And yet, we have seen this play out in x86, with Intel v. AMD, and it worked exceptionally well.
> An equally plausible outcome is that they will not – or that they will each implement mutually incompatible interpretations whilst proclaiming full compliance.
Of course, AMD and Intel were always trying to one-up each other, but that is tempered by the necessity for their improvements to be supported by compilers. By the time an improvement is well-supported, the other side has caught up.
With Risc-V this is even more likely to be the case, because proprietary extensions will simply not be that well supported by major compiler vendors, who have a hard enough time keeping up with the ratified ones.
even when foundational patents expire, licensing agreements and copyright and trademark and other things remain legally enforceable. chinese companies actually did start investing in mips at one point but ended up getting sued. people tried to open source mips years ago but gave up and just switched to risc-v because it's too much of a legal hassle to try to open source something that was proprietary for decades and has all the legacy baggage of multiple previous owners who want to sue you for any reason they can think of. it was easier to just design a new architecture that was open from the start.
I think the issue is then, if you have the same base lineage and you start extending and fixing things, then it will be easy to overlap with new patents that whomever still holds MIPS IP.
RISC-V is mainly a way to avoid IP conflicts, not as a technical breakthrough. MIPS itself was a boring (this is good) implementation of the original RISC papers, but they asserted a bunch of things legally which eventually, along with the legal work of Arm meant that ISAs were effectively owned by their parent corporations.
I'd assert that much like 3rd parties being able to make replacement car parts, that we should be able to make ISA compatible chips. But here we are, RISC-V needs to exist and does, but for legal reasons, not technical ones.
*edit, I forgot to refresh before posting, what bjornnn said.
It's not just China that has an interest. Multinational corporations also hate being charged licensing fees (see Qualcomm vs. ARM). Here's a list of RISC-V members: https://riscv.org/members/
I wrote an RV64IMA emulator recently. I just needed a virtual CPU core that could boot linux, and RV64IMA seemed like the simplest way to do that - and I think that's more or less true.
But then I wanted to be compatible with off-the-shelf toolchains and binaries, and I found myself needing to extend the ISA profile to RV64GC. Not a huge lift, but it involved pulling in a softfloat library. That got me as far as booting Alpine linux.
And then I wanted to be able to boot Ubuntu, which needed RVA23, which was comparatively a much bigger lift, involving the vector instruction set among many other things. At this point I think I'd have been better off just emulating aarch64.
Just like Debian still runs on original x86-64-v1 from 1999, not x86-64-v3 (needs AVX2,FMA, BMI1, BMI2, LZCNT) or even x86-64-v3 (needs AVX-512).
Similarly, Debian for arm64 still requires only ARMv8.0-A from 2011 not even ARMv8.2-A (everything from A75/A55 to A78/N1/V1) let alone ARMv9-A (A710, A510, X2 and on).
Why would they do in the RISC-V world what they totally haven't done in amd64 or arm64?
> All Armv8-A systems that support standard operating systems with rich application environments also provide hardware support for Advanced SIMD instructions.
and
> All Armv8-A systems that support standard operating systems with rich application environments provide hardware support for Advanced SIMD and floating-point instructions. All Armv9-A systems that support standard operating systems with rich application environments also provide hardware support for SVE2 instructions. It is a requirement of the ARM Procedure Call Standard for AArch64, see Procedure Call Standard for the Arm 64-bit Architecture
So, both FEAT_FP and FEAT_AdvSIMD are optional for Armv9-A and Armv8-A.
But both are mandated in cores for "rich operating systems", which basically means it's mandated by the OS.
Near the end of the essay, the author mentions that the folks at Berkeley considered OpenRISC.
Would that have been a better path do go down, to throw a bunch of work, money, and R&D after, or is there anything inherently bad about that design besides delay slots?
I kinda feel that even the smartest people will build great things on crumbling foundations as long as those foundations are available. I'm thinking of NASA embracing RISC-V or anyone who decided to write secure-by-design software in C.
The conclusion is honest, and you can of course brute force any ISA into any role. I used to loathe x86 for that reason, but now that I'm older I respect the game.
I think MIPS is a great example, and even there I don't think there's the bizarre bifurcation of ISA options RISC-V brings to the table.
As a fellow olderster, I can't help but think that after almost 50 years of "ISA X is sooooo much better than x86 it's obvious ISA X is the future and x86 will be dead Real Soon Now (for whatever todays version of x86 is)" I can only shake my head ruefully and say "ping me when that happens".
Controversial Take (that history proves isn't): Software matters; ISAs don't.
x86 chips don't truly exist anymore. They only use it as a compressed ISA for a more capable internal representation that can be freely updated at any time.
I keep seeing this line of reasoning and have no idea why it's relevant. You don't program that 'internal representation'. The software people want to run only care if that software doesn't run. Cyrix, Transmeta,NexGen, Centaur, WinChip, etc., etc, theoretically had "more capable internal representation". The only thing that actually matters is "does it run the exact same x86 software I bought X many years ago" and "does it run it at a decent price/performance ratio". Everything else is dick measuring.
Today, we have Intel and AMD, and some bit-player embedded folks.
This is a load of bullshit that largely exists as copium to explain how x86 did the impossible and made a superscalar CISC processor. x86 is doing the same thing that (to my knowledge) all high-end processors do, yet no one tries to call out those chips as compiling to a different internal ISA. But you also don't see any chips trying to run with multiple ISA modes: the closest you get is 32-bit and 64-bit modes coexisting, or ARM's Thumb instruction set.
Amen. I remember the about 6 months when the benchmark cawboys were screaming that they had to be able to have access to directly program the Pentium Pro micro-instructions because 'that would be so much faster' and no matter how much the Intel architects who actually knew how things worked said "I don't think those words mean what you think they mean" there was some conspiracy to keep the PPro from achieving it's max performance...as if Intel didn't want the PPro to show it's max performance.
I haven't kept up with POWER after POWER9, but I recall it to be a true hardwired control RISC, pure as the driven snow. This had some interesting properties (along with other clever designs like eFuses and pNOR) for creating a really credible security posture. They do have a millicode system and chicken bits for oops moments (which are kind of an opposite risk, if you don't get those right for unexpected problems).
A lot of the implementations have used cracking and grouping. They were/are definitely not doing anything like a 1-to-1 mapping between externally visible instructions and their implementation.
Whenever I see someone say this I'm thinking the following:
If what they say is true, then x86 won because ISA doesn't matter, precisely because ISA is the public instruction set architecture. If you can convert anything to a better representation then the argument of exposing the better representation doesn't actually follow.
Additionally, you are claiming that an internal implementation detail that only Intel and AMD know about is secretly implementing your favourite instruction set, which when you think about it, is incredibly implausible and impossible to prove. It's eerily similar to an unfalsifiable theological claim.
Then there is the silly argument that x86 chips don't exist anymore, when x86 chips have distinctive differentiating factors that make them unlike chips that implement other ISAs. The most obvious one is that x86 is primarily used in the personal computing and server space. This means the chips focus on high single threaded performance with large caches and large core counts plus swappable memory and storage devices, whereas most ARM and RISC-V devices target a completely different space, primarily embedded devices where everything is included on the PCB and there are very few external interfaces. You have to be pretty delusional that an unfalsifiable claim on an internal architectural detail of a CPU core somehow invalidates the rest of the silicon that happens to be on the same die.
I hate comments like yours because they are self defeating and require a lot of effort to debunk.
There's still repercussions to the unaligned variable length instruction set that is x86 though, and the decoder and prefetch have to deal with the insanity that falls out from it... ultimately limiting how parallel the instruction decode and dispatch can be.
X86 is the best argument that you can build a fast efficient RISC-V chip... because the X86 instruction set is a much bigger mess.
It just blows my mind sometimes when designers don't learn insanely obvious lessons from the past, basic stuff like "complexity is evil" and "make the fast path overlap with the most common use cases" and "a standard with N optional extensions is actually N! (N factorial) standards."
That being said all real world architectures seem to have messy corners and warts. RISC-V was a chance to do away with a lot of that and they... didn't?
> X86 is the best argument that you can build a fast efficient RISC-V chip... because the X86 instruction set is a much bigger mess.
I don't think that's actually true. There's weird historical baggage and whatnot. But if you're running in long mode, it's actually a fairly sensible architecture with useful memory addressing modes.
> because the X86 instruction set is a much bigger mess.
One of the things I've been playing with off and on in my spare time is poking at the x86 ISA. And yet, while the ISA does have some weirdness to it, it is a lot less weird than its reputation makes it out to be. For example, the sum total of the opcode form amounts to does-it-have-ModR/M + size of immediate operand (in bytes)... which honestly strikes me as simpler than RISC-V instruction form decoding.
I know there's an earlier criticism of RISC-V that points out that one of the common instruction sequences for which "macro-op fusion" is the suggested solution involves 5 instructions... and I don't think any of the existing chips ever fuse more than 3 instructions?
You've also got tons of prefixes with opcode dependent rules on what's allowed there, the opcode field itself is variable length (I've seen up to four bytes), you've got instructions that treat that immediate field as additional opcode bytes, etc.
The opcode is 5 maps (8, actually, but only 5 are occupied) of 10-bit opcodes, with the presence or absence of 66/F2/F3 prefixes providing 2 of those bits. If you ignore how the manual describes prefixes and look at it like that (which is suggested by the VEX encoding process), the decoding process becomes a lot simpler. In fact, with one singular exception, this is sufficient information to index into a map to figure out how long the immediate field is and whether or not ModR/M is present.
There is a general pattern I've noticed, where people from past generations fail to share the lessons they have learned somewhere that is accessible for the next generations, so they are stuck repeating the lesson.
In particular, the next generation might recognize some aspects that seem bad and be confused over how to prioritize correctly because they don't know any better.
It is just that it is some combination of behind closed doors, for competitive advantage, and/or the new generations don’t want to hear it.
Previous generations had learned long ago that sharing everything in public, or even in patents, was a bad idea for long term survival, a lesson that has now taken on a more extreme form.
They even loudly declared how they were going to clean up all the messy corners and warts.
The underlying truth seems to be that a “clean” ISA doesn’t by nature make the beer taste better, and many of the warts probably have a reason for existing.
My disagreement with the article is mostly the following:
RISC-V is not an ISA, but an ISA generation framework.
If RISC-V would've standardized aarch64 1-to-1, the end result would've still been a huge extension mess, because a lot of people (RVI member) have different requirements and a very happy to build their own subsets, which would then be upstreamed because multiple vendors want the same subsets and compatibility between them. Obviously it would've been better, similar to if RISC-V spawned with RVA23 done, but development takes time and RISC-V International started, because people where already using RISC-V.
RISC-V also is the most DOSed ISA, with people proposing crazy stuff. Just the other day somebody proposed an instruction that would do up to 2^30 16-bit comparisons in one instruction at the largest VLEN. Because they wanted to improve their string processing usecase.
---
In my experience RVA23 matches aarch64 and x86 in uop count (without fusion), code density is better, instruction count is slightly higher. The biggest impact on the instruction count advantage of aarch64 over RVA23 is a single instruction, load-pair, which gets cracked at decode in every high-performance implementation, because it writes to to registers.
The Arm approach to code density is using multiple writeback instructions that have to be cracked and the RISC-V one is RVC. Both prohibit simple linear scaling of parallel decoding, so code density seems to have mattered to Arm enough to make the tradeoff worth it.
It’s kind of funny that all of the complaints about optionality apply equally to Vulkan. Google even created the same profile solution with “Android Vulkan Profiles (AVP)”.
I suspect Vulkan suffers from the same design by committee problem, which similarly caused it to miss seemingly basic features in the base spec that then need to be filled in with extensions and also made it too difficult for developers to want to move too.
Why is he complaining about everything being optional in RISC-V? Isn't that the whole idea of RISC-V? The market can sort it out for themselves. RISC-V is already dominant in the MCU space despite its flaws, and many of them will be solved in due time.
Most MCUs are used for dead-simple solutions, like electric blankets and microwaves with segment displays or LEDs. Whether their interrupts are handled in 44 or 22 cycles doesn't really matter that much.
And RISC-V does have a link register, making returning much faster when the parameters for the interrupt can all fit in registers and no external memory access is needed, as is the case with most MCUs which put the stack in RAM. To fetch the return address an external memory access is always needed even if there are no parameters.
He explains, at length: there is no sane way to determine what the hardware you are running on actually supports, and so there is no sane way to ship compiled code that is both compatible and performant.
We already had the mystery meat CPU wars several decades ago. We know how to make sane ISAs now and should be past that.
You don't need to probe what hardware you're running on because you know being the manufacturer. The code is bespoke for your solution and nothing more. No foreign code is going to run on it.
Different problems require different solutions. An electric blanket doesn't need a barrel shifter for multiplication or even floating point hardware. The ISA can change depending on what's needed to solve a particular problem, not to provide an "one size fits all" solution.
I don't think I've read a more "doesn't actually know anything about how software is produced, but with absolute confidence knows everything about it" post in a very long time.
This ensures (in theory, at least) that even if you're using your linux distribution's openssl library which is more generically targeted, you will get optimal/native runtime performance for your actual CPU.
> You don't need to probe what hardware you're running on because you know being the manufacturer. The code is bespoke for your solution and nothing more. No foreign code is going to run on it.
In practice, this is not the case. The scenarios mentioned in the article involving binary blobs are pretty common, as well as other similar scenarios.
Really, I'm going to go out and say it bluntly: it is just completely freaking stupid to make an architecture where everything is optional but you have no way to query what's present. If you're going to go the optional-pieces route, you have to have a query mechanism of some sort. As the article explains, you cannot even trap instructions on RISC-V to figure out what your core supports, because bad instructions might belong to some other option. Complete. Idiocy.
I'm not an embedded programmer myself, but from what I've heard... it's actually a pretty big assumption that the software people know what model hardware they're running on.
Especially consider the possibility that a product manager decides to swap out the core for a different core to save 5¢ on the BOM. Does the product manager know to ask if the two cores follow the same RISC-V profile? Do the software programmers think to ask? How about communicating the change to all of the vendors or contractors providing you binary blobs? I don't know how likely it would be for a scenario like he author here describes, but it is definitely a plausible scenario.
Even if the core was supported just fine, all of the IO mux stuff is pretty much guaranteed to be different even with the same chip in a different package.
I worked on a project porting from an STM32L073 to a STM32U073, which management were assured was a complete drop in replacement. Well, it was only in the sense that you could drop one onto the old PCB. It became a running joke how many software compatibilities we ran into. My favourite was an "LCD clock disable" bit became "LCD clock enable". And this was for a specifically chip designed to be an easy replacement.
I'm not sure this is a real problem - for embedded you know a priori - for arbitrary desktop/SBC machines, misa will be available in kernel mode and /proc/cpuinfo will be available in user mode.
Well, misa won't be in most cases since you'll be running ins mode rather than m mode for most kernels on an application core (and misa won't tell you about the X* and Z* extensions).
But you'll practically be passed a device tree from SBI that will tell you.
He actually explains this too. You only know at compile time what you're building for. For example with microblaze-V, I often tweak what ISA I'm generating. If I ran the same elf without thinking about it, who knows what could happen given the instruction collision problem
There is a very easy way to determine what hardware you are running on, it's the baseline of the OS.
Armv9-a doesn't mandate FP or SIMD support, but nobody does detection for those, why? Because it's required on the OS level.
Similarly OS are moving their baseline to RVA23 so software can assume all of those instructions are available.
Because nobody will write software for 300 unique hardware variations of a platform that have inconsistent capabilities. Consistency is one of the reasons why x86-64 with extensions like like SSE, AVX2 etc is popular.
Noone uses an 8051 because it's elegant. Billions are still still sold every year because no matter if you learned it in the 70s or last week and no matter who made it, the basics are exactly alike. Software matters; ISAs don't.
I really don't know anything about this space, but you just said that 8051 is dominant because it has one dominant architecture since the 70s. It has hundreds of manufacturers making identical parts.
As you say, software matters. If the Software can't run because of hundreds of extensions that can't be checked for, then you're going to pick a target that works, no? So in fact the ISA matters most: which ISA has the most software? Which ISA means my software runs on the most devices?
If the Software can't run because of hundreds of extensions
The software in the x86 world runs because there aren't hundreds of mutually incompatible extensions. I think the last time there was a major completely incompatible x86 ISA divergence was AMD "3DNow" vs other SIMD extensions. AFAIK the rest were "processor X got feature Y later than competitor Z".
Which ISA means my software runs on the most devices?
Every time I've seen someone use an 8051 in the past twenty years, it's had new, bespoke software written for it. They were more used because they were a known quantity with the patents obviously dead rather than support for existing codebases.
Interesting comment. I suspect without solid facts that new bespoke stuff is mostly either 1) some ARM variant, or 2) some rando US$0.001 Chinese uproc. I think 8051 survives because there's many decades of experience using it, but as I understand the cool kids going into embedded don't think the boomers 8051 is fun and the pool of talent is shrinking fast. SO we'll see what the future holds.
Those aren't mutually exclusive. Some of the sophgo and bouffalo chips have 8051s for always on cores, and riscv for the main cores.
They didn't choose 8051 there for experience, but because it was a tiny core with a decent IPC they could license for a small part, then focus on the main cores. I wouldn't be surprised if they eventually switch to riscv there too.
Also, these 8051 cores tend to be extremely diverse. I don't think I've come across cores from different manufacturers that were actually compatible for real code. They all seem to want to handle accessing 16/32 bit memory differently, have different interrupt details, etc.
Interesting...I don't know much about sophgo and bouffalo chips. Not surprising since the 8051 is patent-free these days. Something I found crazy is how many places someone embedded an 8051 core. Like the tire pressure monitor in every tire these days. Fun stuff.
I believe the market will standardize on certain extensions for specific solutions. No one is going to make a mobile phone with only RV32I, for example.
How can you use consistency and SSE/AVX in the same sentence?
SSE has inconsistencies like SSE4.x vs SSE4a. AVX is an even more mixed bag. There are some 19 AVX-512 extensions and ZERO chips support all of them.
The situation is so bad that AMD and Intel got together to make AVX10 to unify everything. That seemed great, but Intel now has AVX 10.1 and 10.2 in addition to the base set, so there we go again...
x86 is a massive battleground with tons of competing extensions like FMA3 vs FMA4 (why did FMA3 win???) and in cases where one of the competing variants didn't win, we get something like virtualization extensions being completely different between Intel and AMD. There's also the rash of security extensions that have gone through various support and dropped support (not to mention using some of this stuff for market segmentation and further fragmenting the ecosystem).
x86 is anything but consistent if you look into its history (or even it's present).
> but Intel now has AVX 10.1 and 10.2 in addition to the base set
Intel committed to not slicing and dicing the AVX instruction set going forward. AVX 10.(n+1) will not remove instructions that were in AVX 10.n. Feature testing is also easier: a single feature bit and a single version number.
I bet Intel's management will find some new counterproductive way of segmenting the market but AVX-10 (and therefore AVX-512) should be safe now.
>"RISC-V is already dominant in the MCU space[...]"
Where are you getting the idea that RISC-V is dominant? As someone who works in this space, that doesn't jive with my experience or the sources I've seen.[1] 32-bit microcontrollers only recently achieved a majority market share for gosh sakes!
RISC-V is claiming that they have achieved 25% market share across selected segments, but they're still behind ARM (and x86).[2]
Risc-v is nowhere near dominant, people are just being swayed by headlines such as Western Digital or Nvidia shipping billions of risc-v cores.
I do find it odd that you go on and compare to x86 marketshare however, the topic you've quoted is very clearly about MCU and whilst 8086 MCU still exists they haven't been used in greenfield projects for decades. Let alone any more recent x86 implementation.
It's used widely in Chinese stuff (which is basically everything) so in terms of volume it's probably already dominant.
In terms of dollar volume ARM is still the leader, especially for higher-end (application level MCUs) stuff. RISC-V MCUs with MMUs or MPUs are scarce at the moment.
MPUs are more common. The Physical Memory Protection option is basic and allows ranges of memory to be set unavailable in user mode. A few well-defined ranges do let you lock a user process down securely but it's not a real MMU. Low-end microcontrollers don't have enough RAM to warrant a real MMU.
The RISC-V core in the Raspberry Pi RP2350 has PMP as do the ESP32 cores.
Started reading, however I wanted to add this in: a lot of people expect RISC-V to do too many things, and nearly all of those things are "beat every other architecture out there in every way/shape/form, while also being open".
The reality? The fastest "available" RISC-V CPUs don't match the best chips in terms of speed, power consumption, or die area. "available" obviously means the chips that have been released to the public and can be independently benchmarked.
I do think that is okay, however I also think that those involved with RISC-V aren't helping much, and current attempts at standardizing seem to be just creating a bigger problem.
That being said, RISC-V does seem to perform well in specific niches.
- A big problem with extension detection RISC-V has is that there's no central authority mandating vendors to not overlap things (obviously, given RISC-V being an open standard), so basic bitmasks for supported extensions is generally rather problematic (and of course even if you collected a standardized bitmask of all extensions from all vendors, it'd grow quite massive quite quickly); you'd at least want some grouping/marking by vendor, if not full extension strings. That said, it would be nice to at the very least have some standard in-memory blob format if nothing else, that you could query from any OS/libc. (which maybe somewhat-exists to some extent with a C API meant for libc, but as-is still doesn't attempt to figure out vendor extensions).
- many, if not the vast majority, of aarch64 TBZ/TBNZ are probably branching on a boolean; something RISC-V can also of course do in one instruction. Generally, comparing instruction frequencies across ISAs is messy if not approximately meaningless due to different sorts of things existing for solving the same tasks.
- "Having this happen means that instead of a clearly-understandable crash you get ... well ... anything." - RISC-V will do you one better - it doesn't even guarantee a crash when an instruction isn't defined at all! Overlapping extensions is definitely messy for disassembly, sure, but that's also just basically unavoidable as long as RISC-V is open (see my first point). (perhaps there could've been stricter rules for reserved-for-standard encodings than reserved-for-vendor ones? of course still doesn't help vendor encodings, nor non-compliant vendors)
> The spec says that bit must be zero, and yet no encoding uses the space opened up by that bit being one.
The spec says "the code points with shamt[5]=1 are designated for custom extensions.", so the space is specifically reserved for custom vendor extensions.
So, if I wanted to add a custom "dzaima.c.clear_top_n_bits rd, imm5" instruction, that's space I could safely put it in, knowing that no future standard instruction will be added there that I may regret overlapping. So while that space goes unused in the standard, its existence helps with the overlapping encoding problem!
> For I-type instructions, bit 1 [...], bit 11
Of course, that's cherry-picking two of the 25% of bits that have multiple positions they come from, and specifically 11 as it's the worst one. Full stats:
1 position: 24 bits: (everything that's not listed below)
2 positions: 7 bits: 0, 1, 2, 3, 4, 12, 20
3 positions: 1 bits: 11 (the single worst case)
So that's like 9 muxes for merging all immediates to the same place (or less of course if the different encodings' immediates go to different places), the rest is just wires.
Obligatory note is that some of the funkiness is to place the sign-extended bit in the same bit position, so some saved muxes from that.
Now, I am a "software person who's never written verilog", but I highly doubt a 3:1 mux is as cheap as a 2:1 mux in silicon, so even if you always need to merge in the sign bit, reducing the number of cases is still beneficial.
Compressed does make it a ton more ugly though (combining both 32-bit and 16-bit instruction encodings, placing the 16-bit ones in the low 16 bits):
Fun! (lsl being a subset of the bitfield extract instrs is neat; tbz's similar-functionality 6-bit field is just entirely-differently placed though. Also.. using the Rd slot for an input-only Rt? that's one thing RISC-V doesn't do, even across compressed and 32-bit instrs!)
Some stats on an aarch64 binary of my current main project (1.6MB .text, 6600 symbols as per whatever "nm the-binary | wc -l" includes, from "objdump -d the-binary"):
19546 /tbn?z/
18029 /tbn?z.*, #0x0/ (but this includes boolean checks)
224 /tbn?z.*, #0x1f/ (i.e. 32-bit x<0)
1139 /tbn?z.*, #0x3f/ (i.e. 64-bit x<0)
154 other immediates
Said project doesn't do fixed bitfields much (there are some, but a chunk of those test multiple bits) so unsurprisingly not much. (I could imagine that the kernel has significantly more, but it's an edge-case (though perhaps an important one) of being basically massive amounts of fixed configurable glue)
That is quite a good bit more evenly-spread (the "..." is 5159 instrs).
Wonder what's up with bit 21; if whatever uses it so much is repositionable (and not an aarch64-specific thing), could save like 2KB on x86-64 via putting it in the low 8 bits instead.
> Say you want to store a byte to a register plus offset. What range of offsets can a [compressed] 16-bit instruction encode? Zero through three.
If a compressed instruction could load or store a word to a word-scaled offset 0-3, relative to a register base address, that would be quite useful. It could be used for accesses to all structures four words or smaller.
Honestly, I would feel uncomfortable if I were designing an instruction encoding and came up with some addressing mode format where there are two bits for a displacement. I would pull myself aside and have a word with myself. That's just me, though.
And personally, I'm not even sure it crosses that bar.
RISC-V somehow manages to be more fragmented than x86 (which is impressive), and just can't compete on instruction density.
I think a large part of the issue with RISC-V is that it predates (public knowledge of) ARMv8 by a year or two, so it couldn't use it as inspiration. If you compare RISC-V to 32-bit ARM, the comparisons are much more favourable.
The article makes the case that RISC-V achieved code density the wrong way. Instead of compressed instructions, ARM has fixed-size instructions with richer semantics.
The fact that it's only "competitive" with aarch64's code density is a solid black mark against RISC-V.
The only reason it's "competitive" is the compressed instructions, which means it's paying all the costs of variable length instructions, yet only getting marginal benefits. IMO a modern ISA taking advantage of variable length instructions should be able to absolutely smash the code density of a fixed width ISA like aarch64. At minimum, it should be competitive with x86 code density, if not smashing that too (because x86 has a lot of legacy baggage)
Compressed instructions aren't a bad idea for very small cores. They give you a decent code density boost with minimal added complexity.
But for large cores you either want to go full fixed length (like AArch64 and Qualcomm's proposal, which bought non-compressed RISC-V into the range of AArch64) or adopt a much more complex variable length scheme that can actually beat x86 on code density.
There's a huge difference between 2/4 byte variable density and 1-15 byte variable density. And as I've said in other places, my experiments showed that it ended up being kind of across the board less than half a pipeline stage to handle C instructions, kind of orthogonally to decode width.
It is a different front end design, so that's why Qualcomm didn't want to reengineer their aarch64 core more than they had to, but the rest of the riscv community was right to not embrace it.
Not to mention that a lot of the aarch64 derived pieces in the proposed qualcomm extension are almost certainly patent encumbered. Qualcomm can absolutely handle just about any patent fight, but other risc-v companies can't.
I agree that 16-bit/32-bit variable length would struggle to beat x86. But I suspect it could have gotten close, simply because x86 wastes a huge amount of its advantage on legacy cruft.
The important point is that there is no reason why a 16-bit/32-bit encoding shouldn't have smashed Aarch64's 32-bit only code density.
My secondary point, is that why should RISC-V limit itself to just 16-bit/32-bit? It has the encoding space set aside for 6 bytes, 8 bytes, 10 bytes and all the way up to 24 bytes (which is overkill). If it's already paying the variable length tax, it should be making better use of it. IMO, a 2, 4, 6, 8, 10... byte scheme should be able to massively improve on x86's code density.
> I agree that 16-bit/32-bit variable length would struggle to beat x86. But I suspect it could have gotten close, simply because x86 wastes a huge amount of its advantage on legacy cruft.
I'm saying the opposite. Maybe some theoretical CISC-V would leave RISC-V behind, but x86(and -64) makes wild choices for instruction density, and RV64GC already clearly beats x86-64 in .text density.
> My secondary point, is that why should RISC-V limit itself to just 16-bit/32-bit? It has the encoding space set aside for 6 bytes, 8 bytes, 10 bytes and all the way up to 24 bytes (which is overkill). If it's already paying the variable length tax, it should be making better use of it. IMO, a 2, 4, 6, 8, 10... byte scheme should be able to massively improve on x86's code density.
There's nonlinear issues as you add more options. A 16-32 decoder is pretty simple, a 16-32-48 isn't the worse thing in the world (and a 32bit immediate might make it worth it), but you start to hit weird explosions in gate count once you go much past that. Hence x86's splitting into essentially multiple front end banks in modern designs, and even then typically only has one decoder per bank that can decode everything, and even that takes multiple cycles for some instruction sequences, even just to discover the length.
The larger lengths in the RISC-V spec are more targeted towards bespoke stuff like GPGPU that's maxing out issuing a single instruction per instruction stream anyway. When you look at shader machine code, it's clear density was essentially an afterthought, but they love them some 64bit wide instructions. Which unsurprisingly is pretty much the same width of vertical microcode in archs that still do such a thing.
> and RV64GC already clearly beats x86-64 in .text density.
Maybe I'm misremembering. Or maybe the numbers I'm remembering took into account the fact that most compilers unroll more aggressively on x86 than on targets they consider to be "embedded" (another pet peeve of mine)
I stand by my assessment that the code density of rv64gc (and especially rv64g) is lower than it would be if they had actually put a focus on code density.
> A 16-32 decoder is pretty simple, a 16-32-48 isn't the worse thing in the world (and a 32bit immediate might make it worth it), but you start to hit weird explosions in gate count once you go much past that.
Not sure I would say 16-32 is simple, certainly massively simpler than x86. My point is that you have already paid the tax for going variable length, and 16-32-48 isn't that much more complex. And probably worth it for 32-bit immediate/offsets.
And maybe 16-32-48-64 is worth it... Hard to tell, but I wouldn't entirely rule it out without study. The advantage would either be immediates/offsets that are too big to fit in 48 bits. Or some kind of VLIW style scheme which actually packed three 20-bit instructions into aligned 64-bit packets. (Or other mixtures of sizes like 30-30, 30-15-15, 40-20, or 15-15-15; We are talking about a complete break from RISC-V. There is a thread somewhere on HN where we brainstorm something like this).
But beyond that, no point really. Just pointing out that RISC-V reserved the space.
Maybe I need to prototype the 64-bit aligned packets idea someday, at least far enough to get instruction density numbers.
It is, with a prefix encoding, you can reuse the RVC decode path 1-to-1 and get the 48/64-bit instruction starts with a simple bitshift (or simply handle the 48/64-bit instructions via the fusion path). This seems to be the encoding direction RISC-V is headed in.
> The fact that it's only "competitive" with aarch64's code density is a solid black mark against RISC-V.
Arm uses complex instructions with multiple writeback, that require cracking, to improve code density.
RISC-V uses a variable length encoding to improve code density.
Both have anaougus decoding complexity, but RISC-V achieves higher code density, while impacting the cost of things before decode (how much, idk).
But imagine the code density you could get combining both strategies.
> Arm uses complex instructions with multiple writeback, that require cracking, to improve code density.
While smaller cores have the option of cracking the multiple writeback instructions, many arm cores just pay the extra cost of having a 3 read, 2 write register file, so they aren’t actually cracking those instructions.
They do crack other instructions.
But the cracking seems to be more about ALU limitations (aarch64 has instructions that can do both a shift of any width and an add, but the ALUs might not support this, or only support smaller shifts of 1-3 bits (useful for addressing)
What this means is that despite the cracking, each μop in an aarch64 core is quite a bit more powerful than a typical RISC-V instruction (especially compressed instructions).
So to be competitive on backend performance, a high performance RISC-V is going to spend a lot of resources post-decode doing massive amounts of instruction fusion to try to get μops of similar capabilities to aarch64 (or just settle for simpler μops, and pay scheduling costs of more μops)
So the costs of the RISC-V compressed instruction approach aren’t just limited to pre-decode.
> While smaller cores have the option of cracking the multiple writeback instructions, many arm cores just pay the extra cost of having a 3 read, 2 write register file, so they aren’t actually cracking those instructions.
No, every high performance core I know of cracks them at decode, some re-fuse some of them after rename (Apple).
Because otherwise you would need to rename up to 4 destinations per rename slot, effectively 4xing your already limiting rename stage.
Cracking other stuff later in the pipeline isn't expensive.
Though, I guess fusing after cracking makes things easier because you don't actually have to search for fusion candidates (supported by the fact that Apple's Firestorm doesn't seem to make any effort to fuse things that aren't alu + branch, crypto, or amx)
Yeah, fusing is probably easier, if you already know what to fuse.
On the other hand, if you want to fuse load pair on RISC-V you have the entire rename stage to figure out which uops can be fused independently of the rename stage, if fusion haopens after rename as well.
Despite my curiosity, I explicitly refused to agree to Apples terms for accessing those documents, because they were very draconian. The terms absolutely forbids using the information for anything other than optimising software for apple devices.
Discussing the design tradeoffs of RISC-V μarches couldn't be further from "optimising software for apple's devices".
> On the other hand, if you want to fuse load pair on RISC-V you have the entire rename stage to figure out which uops can be fused independently of the rename stage
That's a good point.
If some RISC-V μarch was going to invest the extra gates for a complex fusion setup, the search isn't actually going to slow anything down, as it can run in parallel with other frontend operations (like renaming).
I always just assumed fusion was done as early as possible, only considering instructions that are right next to each-other (that's certainly the intent of the RISC-V spec), and then resolved immediately after decode.
But maybe it's better to do it right at the end of the front end; After renaming, during insertion into the scheduler.
2015 is when it started to gain steam as a community run project.
But version 1.0 of the spec [1] was released all the way back in May 2011, and the first RISC-V chip was taped out at the same time. This is 5 months before ARMv8 was even announced, and we didn't start seeing actual aarch64 chips until late 2013.
And TBH, I'm not sure anyone realised just how good of an ISA aarch64 is until quite a bit later.
RISC-V 1.0 isn't binary compatible with modern RISC-V, they hadn't frozen the encoding, but rough design is all there.
That is a strength, not a weakness. It allows for things like 64-bit immediate loads, 32-bit branch offsets, and nearly unlimited future extensibility.
With RISC-V, multiple instruction workarounds are needed for all of the above, and those sequences are usually sequentially dependent ones so they can't be run in parallel. i.e. the insanity of loading a 64-bit value through repeated 12-bit immediates with shifts, using multiple instructions to compute branch offsets, and RVV needing setvli instructions everywhere due to not having opcode space to encode vector length/type.
AArch64 is better, but still has problems with limited opcode space when it comes to future extensions. They've had to make "start mode" and "end mode" for SME to save on opcode space, and future compromises will likely be necessary.
Considering just how many of the problems seem to come from RISC-V being a clean-sheet design, I suspect we would be better off not doing another.
What I am interested in is the idea doing an AArch64 style revamp of the ISA, were much of the non-encoding semantic stuff is kept, but the entire instruction encoding (plus all the CSRs, and other things) are reworked to be sane.
You might even do two reworkings in parallel, with one variable-width encoding optimised for microcontrollers, thumb-style; And the other being a fixed-width encoding optimised for wide out-of-order cores.
And at the same time, you make a bunch of extensions mandatory, and unify others into bigger chunks; Code compiled to one of these two encodings would know it had access to a much wider range of instructions.
The idea would be that any C code targeting RISC-V can be compiled to this encoding with close to zero changes, and that mechanical translation of exiting RISC-V binary code should be "possible", as none of the underlying semantics have changed. And the same would help any core wanting to natively support both (or all three) encodings, you would only need a front-end translator.
I feel like that's largely mitigated by profiles. RVA23 is really looking like it'll be the modern base target used for high performance application processors and it makes mandatory pretty much everything you'd want for those use cases, and other comments by people familiar with designing RISC-V CPUs mention that the variable length encoding can be dealt with in a very simple manner that doesn't even add another pipeline stage so it doesn't seem like it's all that big of a deal while also bringing in benefits in code size reduction. Not everyone is adopting it, but several major players have set the stage by mandating it.
This and exactly this. If there is anything I learned in the past 15 to 20 years, I doubt it will be any different. The mentality of development is just different.
I want the iteration of the product that is in its 2nd or 3rd official iteration. Where you have a lot of learning done and battle tested. Preferably without the backward compatibility to create something truly beautiful. Would it be perfect? Of course not. But it will be Great.
I so wish ARM had some counter offering. They might as well give away their their low end design for free.
I was excited when I heard about the project just after it started.
However, past experiences taught me to wait before getting excited about the new 'shiny thing'. I did it differently with RISCV. I waited.
I am glad I did.
It took a long time for actual silicon to appear.
Also, the silicon today has all the facepalming special cases mentioned in the article.
Its almost like those old soviet era cpus that had the list of bad instructions handwritten on the package.
Overall, RISCV was a minor spin on MIPS, but without really learning from other processors.
So why is everyone still pushing for it?
It has the words 'open' on it. People pattern match on that marketing.
As part of that marketing, they also pushed this attitude from the project... 'RISC won'.
I think Chester Lam said it best when he wrote his essay stating that RISC didn't win... OoO archs won. I couldn't articulate that nearly as well as he did.
If you haven't read it, I recommend it.
So, yeah, here we are.
Many people will follow the bandwagon, but they will find that RISCV will not make a significant difference.
I am glad we still have Arm (in all its many forms), x86, and others.
(btw, despite my username, I don't think x86 is the best either :-)
Also, if you aren't trying to ship a product, you can experiment with ISAs on an fpga.
Yes, fpgas are a lot slower, but they are also a lot more fun.
Especially with the great work done to create open source toolchains.
Heck, if you are really serious (slighly crazy), you can build your own chip.
For the foreseeable future ASIC shuttles are available at prices under $10k. (again, you have to be a little crazy)
I'd say RISC won, when you consider how "RISCy" x86 is[1] compared to the ur-CISCs (68k, VAX) that RISC projects were in opposition to.
[1] Not because of often-called "risc like" microcode engine, but because the most complex addressing mode on x86 usually decodes two microinstructions, and decodes in single cycle. In comparison VAX needed separate pipeline for instruction decoding.
> In comparison VAX needed separate pipeline for instruction decoding.
That's how the VAX 9000 and NVAX did it. It's not the only way. It is absolutely possible to decode a number of normal VAX instructions in parallel using a pipelined decoder similar to x86 decoders. It is also possible to use a µop cache similar to many x86 and ARM implementations.
Fallbacks are only needed for the weirder addressing modes and for instructions that positively beg to microcoded (system calls/protection level transitions, some bit vector stuff, COBOL decimal stuff, block copy/scan/fill/compare, probably POLY) and startup and interrupt/exception handling.
DEC never did this but they absolutely could have.
X86 does not really need pipelined decoders like NVAX did. The complex decode for x86 is the fast path for NVAX without going into CSU. And CSU is where all the more complex addressing modes on VAX end up going - the complex instructions are executed, yes slowly, but in separate unit once CSU finishes the decode for them (and even for packed decimal stuff I-box can theoretically decode in nearly one cycle if all operands are register or immediate). uop cache I'd admit could help for some cases, but still leaves you with even a simple ADD instruction possibly expanding into ~7 uops, maybe 3-4 if we assume big fused equivalent of LEA but then 2 of those will still stall with memory requests.
DEC didn't try to parallelize the decoder further because it already could face 56 bytes for a single instruction, and the NVAX design was costly as hell. x86 in comparison has limit of max 15 bytes per instruction, and most instructions in x86 code fall in 4 bytes
> The second category for big-compute is actual desktops and SBCs that do interactive computation, browsing, gaming, and other such "desktop work". I do not expect RISC-V to be a serious player at the top of this market. Simply put, the architecture is not designed for it, as pointed out above. Additionally, this market has the margins to afford licensing a much-better-designed aarch64 core from ARM, and gain proper support from a much larger corpus of software. Before you get your megaphone to shout about "openness", please note that the openness of the RISC-V spec is not relevant here at all, because an open spec does not magically materialize a well-designed out-of-order core for you for free. And if someone were to design a good out-of-order core, they would not be giving it away for free. An open spec does not mean every implementation is free.
I basically disagree with this. Not because this isn't the current state of things (it absolutely is), but because we're at a bit of an inflection point where mooore's law has proved itself to be an scurve, and we're very clearly well into the top half of it. From that, gate counts per core will also start to ossify, and that means the longer latency for getting an open core design off the ground initially will also start to make sense.
If those people build cores like linux kernel is built design-wise, i will PAY to watch the spectacle.
You do realize that Linux got basic SMP support 3 years after NT, and it was shaky for a while after? It still does not have reliable sleep-wake. And it only added native async file i/o in 2019, while NT has had it on the same hardware since 1993? So.. i'll expect an in-order core with an IPC south of 0.5 that cannot exit low power sleep 30% of the time in a decade or so.
> You do realize that Linux got basic SMP support 3 years after NT?
Linux started about three years after NT did. And NT could only support 64 processors for a long time when Linux could support thousands.
> It still does not have reliable sleep-wake.
Neither does NT really. Both depend on ACPI for the systems you're talking about, and it's the platform interface that's ultimately fucked.
> And it only added native async file i/o in 2019, while NT has had it on the same hardware since 1993
And has beaten NT on IO throughput for decades, and even now windows ships with a linux kernel integration because running Linux on a hypervisor is far batter for filesystem ops than running those on NT.
> So.. i'll expect an in-order core with an IPC south of 0.5 that cannot exit low power sleep 30% of the time in a decade or so.
There are already open source OoO RISC-V cores.
But the point originally isn't to be some Linux fan boy (I've written a decent amount of NT kernel code, and have a lot of respect for NT and the things it did right). It's to point out how the upcoming changes inherent to how chips are made and the latencies between gate count targets will better support open collaboration. And once that's supported properly, open source has a tendency to kind of snowball.
I mean, Apple is different from pretty much every other manufacturer here. They collborated in the design of aarch64, and a rumored to own a lot of the base IP themselves which they've cross licensed with ARM. It's very close to AMD:Intel::Apple:ARM when it comes to aarch64. That heavily changes the licensing costs. My point isn't that RISC-V is markedly better, but instead that it's equivalent from a perf achievable from in the same nexus of PPA and NRE effort. So there's no reason for Apple to take the pain of a leap with no real gain, but NRE losses.
I would expect to see RISC-V Android phones (probably initially out of China, despite ARM China) within the next few years. They've been busy bees since RVA23 was ratified with a bunch of Chinese companies making changes to optimize AOSP for RVA23. I've also heard on the grapevine that NT already has a RISC-V port internally, but take that with whatever grain of salt you feel like. But Microsoft has already been contributing to the RISC-V specs (they contributed to Ztso for instance).
There is zero chance that Apple doesn't have MacOS and iOS running on RISC-V in the lab.
They did that with x86 and Arm half a decade before any announcement about a switch, not to mention a number of other ISAs that didn't make it to shipping (e.g. M88k) and probably ones that word has never leaked about. IA64, anyone?
They're too large and rich and risk-averse to *not* do it.
Not me for sure. I have no idea about you. Of household name companies I've only worked at Mozilla and Samsung R&D. And SiFive if you count people in threads such as this.
I could of course be wrong but I think the publicly known history sets the pattern pretty reliably for the speculation.
What does this have to do with anything? You do know that a bunch of American corporations are shipping RISC-V cores, right? Including Jim Keller's current company, Tenstorrent.
Chinese scale is one way RISC-V could win. If China suddenly starts reaching <5nm process nodes at scale and uses RISC-V, they'd flood the market with cheap high performance RISC-V chips and probably start using them in their domestic Android phone market.
Linux is decent for its core use cases, but it is far from a solid pro-grade OS in a lot of areas... and in the areas it did get there, it took a long time to get there.
The future set of people who once would have "work(ed) for free to design you a state-of-the-art kernel"? If the tail is long enough passionate hobbyists will do it because they love it...eventually.
I'm not sure the gate count argument works in RISC-V's favour.
While RISC-V is quite optimised for gate count for small cores; In large wide OoO cores the variable length encoding really bulks out the decoders.
You basically have the same requirement as x86, where you have to attempt to decode a 32-bit instruction every 16-bits (because there is no alignment guarantee for 32-bit instructions), and then cancel out the invalid ones. It's not quite a bad as x86, you only need to look at two bits, but it still forms a long dependency chain, and probably requires at least one extra decode stage with complex routing to pick out all the valid instructions.
You don't really have to have a separate decoder every 16-bits. What you have is a length decoder every 16 bits (so just a single nand gate over the first two bits versus a huge chunk of the prefix/opcode part of the decoder for x86), which then feeds into a set of muxes for the actual decoders. The actual increase in complexity ends up coming from the critical path of the stack up of length selection affecting start addresses (and therefore mux selections) for later instructions in the block, but even that's not nearly as bad as it sounds because you can use the same base trick behind a carry lookahead adder. When I did some experiments a while back, it ended up being less than half a pipeline stage overhead versus fixed width instructions kind of across the board.
So not nothing, but very far from a deal breaker even for wide 8, 10, or even 12 wide cores.
Yes... but then you are kind of wasting a pipeline stage on nothing more than length decoding.
I suspect a design with a full decoder every 16-bits might actually win on everything but gate count, mostly because it can deal with variable length instructions and variable number of μops per instruction in the same step. A decoder that doesn't output a μop because it was clobbered by a previous instruction, can be handled the same was as a decoder that didn't output a μop because of μop fusion.
Actually, that approach might actually eliminate the need for the extra pipeline stage (just at the cost of gates).
It's certainly not a deal breaker. But it's a valid criticism of the ISA.
I said easily less than half a pipeline not a full stage. Everything kind of shifts around a bit because of that, and it ends up being a pretty different design than a fixed width front end because of it (hence qualcomm's objections), but it's not clearly worse.
And for better than aarch64 density, it seems to make a lot of sense.
Ok, so you doubled the number of decoders, how is that not significantly better than x86?
I'm not even sure you have a point with regards to it being a valid criticism. Doubling the silicon area for instruction decoding probably costs nothing, because if you have a simple decompression stage, the maximum number of decoders is already doubled in the first place, because you're hypothetically encoding twice as many instructions to begin with. If you can double the decoders in the decompression stage, you can probably get rid of a separate decoding stage altogether and thereby reduce the cost to literally nothing.
Look, it might not be obvious but in university I once had to design an ASIP and then do the floor plan with Cadence and the area of the SRAM dwarfed everything to the point where my ASIP was a tiny vertical column in-between two SRAM chips. I personally was shocked by the fact that I struggled to even find my ASIP on the floor plan, because it was maybe ten standard cells wide in-between the SRAM blocks. Like, ridiculously tiny to the point where it is hard for me to even care about the area the ASIP took up.
> you can use the same base trick behind a carry lookahead adder
YESSSS.
I've been pointing this out for years and years.
By the point that you're looking at the same propagation delay as a common 64 bit adder you're decoding 64 chunks of 16 bits per cycle. That's 128 bytes, or a 32-64 instructions wide decoder.
That is so much wider than anyone is making or contemplating — or that even makes sense given the size of basic blocks — that it's just a non-issue.
And even if you go to those extremes, the biggest nay sayer says the cost of the design flaw will require you to double the number of decoders, which hardly sounds like a big deal to me.
The annoying thing about RVC is that 32-bit instructions can now appear misaligned. I would be far less annoyed about RVC if it didn't break alignment, as you could solve the problem with a bunch of RVC-only decoders at the misaligned offsets.
So you either need (almost) double the number of full decoders, or a length decode and a bunch of shifters to get each decoder the right input bits (which get larger the wider the front end is. The 8th instruction can be at one of 7 possible offsets)
I don't believe this will impact performance in practice, because nothing forces CPU vendors to implement fast compressed instructions. If compressed instructions become slower than non compressed instructions as the instruction decoders get wider, compilers will stop emitting them in the future.
Nobody in high-performance does fixed-width instructions that allow lineary scaling parallel decoders. Arm basically requires certain instructions to be cracked into multiple uops before rename. That ends up analougus to decoding compressed instructions.
RVC increases complexity before decode, how much that impacts things idk.
> […] we're at a bit of an inflection point where mooore's law has proved itself to be an scurve […]
Well. May's law[0], which states that:
Software efficiency halves every 18 months, compensating Moore's Law.
effectively counterbalances Moore's Law and, with continued technological process improvements and optimisations, the proverbial arm's race is likely to continue for a very, very long time – just a few days I was reading a wonderful article from 1998 on the state-of-the-art DEC Alpha 21264 CPU which mentioned the 21264 and POWER3 as the world's most complex CPU's each boasting 15+ million transistors and also mentioned the equally state-of-the-art 0.18 micron processes. The 3 old year M3 Max design, in comparison, supplies over 90 billion transistors to the mainstream consumer.
And the M5 doesn't have 500B transistors. We're well into the beginning of the ossification. Hell, it arguably started ~2006 with the end of dennard scaling leaving us with Tomasulo OoO cores being the design that makes the most sense for application cores, just getting wider over time as we get more gates.
As I’ve come to understand it, standards simplify intensionally, not extensionally. For those who select a part that is compliant with a standard, more standards to choose from is better because engineers are able to make better tradeoffs; they’re not forced to select a part that does way more than the application needs thus making the product more expensive if there are lots of “competing” standards: some do less some do more.
For RV, a litany of standardized modules creates a system where each capability that the module provides will have a standard interface. No manufacturer is forced to invent extensions bespoke to their implementation, but they’re not forced to support everything the most powerful models do either.
Sure, the constellation of features is no longer a general purpose computer in the retail context, but rather an ASIC appliance the ends up incompatible/useless rather quickly.
Maybe Gentoo could tame that level of chaos... or people just buy ARM64 again knowing the software ecosystem already works. =3
The RVA point releases don't add new mandatory features, so every RVA23 complient board is also RVA23.1 complient.
They only add new optional extensions.
Until people admit they made the same mistake as ARM6 fragmenting the architecture focus, its adoption will probably continue to stall under each firms hubris. =3
Is it though? Is it really? Outside the HN rant circles which want to return back to times where you needed an adapter for every single laptop model or be shit out of luck for connecting your mouse or projector?
don't see how? the last section is pretty explicit:
> None of this is to say that RISC-V is doomed. As I said, I fully expect it to take over the space currently occupied by [...] Much like the linux kernel -- the price is right.
It's interesting that this quote closed it for you, because that quote is what triggered my take.
I read that as a hat tip to the legendary argument, and a partial adoption of Linus's rebuttal, “Linux wins heavily on points of being available now.” Besides the general tone, I guess.
> After being asked for the Nth time to explain, I decided to put it all down in one place so that I could simply link to it when asked next.
Bookmarked, because I've needed the same.
The worst part of all this is that they really should have known better by now. In 1980 you could make these kinds of mistakes, because this was pretty new territory. In 2020, doing this just makes you stupid. Or ignorant. Or both.
6809 is a better exemplar, but, yeah, we knew this stuff way back when.
The problem is that everybody around RISC-V wants to sell IP instead of a chip. Most of the worst brain damage follows from that.
The rest of the brain damage follows from "We want to compete with ARM A-Series cores." No. Just ... no. Nobody willing to spend that much on a processor gives one iota of damn about ARM licensing fees.
So, the semiconductor market wants a cheap, consistent chip that operates in the deep embedded space while the RISC-V ecosystem considers the mere thought of that to be icky beyond reason. And China will push on this like Longsoon and pray that somebody figures out how to make it not suck (Prediction: they won't succeed.)
And, the worst part is that RISC-V has basically lost its window. The single possible advantage that RISC-V had was that as people converged to a shared tooling ecosystem it would create lockout. Unfortunately, that convergence never happened so, at best, we got some shared compilers. And, now, AIs can basically one shot all your other tools around it and probably the compiler not far behind. And there goes your ecosystem lockout.
I think a lot of this criticism is completely true. However it's also overblown. I do think the ISA matters, but little mistakes like these definitely don't matter enough to preclude making M-series class chips. The reason it hasn't happened yet is simply time. It takes a really really long time to build up to that level of performance.
They've definitely gone overboard on the optionality stuff though. I don't think it matters too much for the actual CPU design but it makes verification and writing portable software a huge pain. Profiles definitely help but still...
Oh also I feel like you could probably come up with an equally compelling list about any other ISA. It's not like the fact that something has flaws means it's bad.
1. You have a microcontroller. You're compiling code yourself and the docs tells you what features are available and which compiler flags to use.
2. You are writing application code. In that case you simply target RVA23.
The edge case is the same edge case where you use CPUID on x86, I.e. you want to target say RVA23 and RVA28 in the same binary. In that case you do have to use the OS APIs to discover what is supported... which is slightly annoying, but in practice you're just calling a different function.
In theory `mconfigptr` will eventually make this a lot nicer but nobody has put in the effort to define how it works yet (last I heard they were looking at ASN.1 sick emoji).
When I looked into mconfigptr some years ago I thought it looked like a swirling vortex of pain that might produce something useful some day. Good to see it's still being worked on. Sad to hear ASN.1 is still involved.
I added an "misa but more bits" register to my core, using the bit assignment from the RISC-V C API, so at least until then I know what extensions each instance of my core implements. https://wren.wtf/hazard3/doc/#reg-h3.misa
Linux folks seem to have already put a lot of the mconfigptr info into the DT blob anyways.
ALL chip designs are an exercise of minmaxing these 3 variables:
1) power
2) performance
3) die area
SOME chip designs also care about a 4th:
4) die area.
NO design has the best of all...it is impossible since you have to trade 1 for another. The reason x86 has been dominate for so long is that is strikes a good balance across all areas, especially #4. A good balance is what you need for a good chip.
EDIT: oh and you can't beat the system I mentioned above. The laws of physics are the reason why.
You forgot the variable that RISC-V chose to maximize:
5) Weird principles that are completely detached from anyone's actual needs and that are carried to a length similar to religious convictions.
My biggest personal pet peeve about the architecture is the JAL instruction.
That is, PC-relative jump and link immediate, which jumps to an PC + sign extended immediate value and stores the address of the next instruction in a register. This is your most basic function call instruction. It only has an immediate range of 21 bits. Even a few bits scavenged from somewhere would really help it, ±megabyte of range is in the vicinity of what you need for internal calls but not generally enough.
It's a 32-bit instruction, so why can it only support 21 bits of immediate? Because the people who made RISC-V decided that implicit register arguments are works of the devil, and that you need to use any register as argument for any instruction. Therefore the RISC-V JAL instruction contains a 6-bit field for destination register, which is where they store the next instruction address. Never mind that there is not and will never be a compiler that emits anything but the ABI compliant return address register "ra" to that field, we decided we won't have implicit arguments so by god we are going to pointlessly sacrifice 5 bits⁰ of space in every single fucking branch, often forcing the user to construct the address in a register and use more instructions instead, which is much worse than it sounds, because branch prediction is easier for immediate branches.
This is not the biggest actual problem with the architecture. They added an instruction that adds upper immediate bits to PC, which the any core that implements instruction fusion fuses with jalr. But that sacrifices the low-end, that doesn't fuse anything, and uses two instructions for an extremely common pattern that everyone else manages in one. The reason I hate this one so much because there is no actual reason to make this mistake. A five minute conversation between two engineers should have killed this one in the crib, literally everyone knows not to do this. Apparently other than the RISC-V folks.
0: I give them one bit, because the opcode is short and they use the zero register to suppress the link and turn it into a normal jump.
Everything being an optional extension is covered by the article. It's bad enough for OpenGL and Vulkan but to burn that into silicon and not have a reliable way to detect them is way worse!
> So what does it even mean to comply with the spec then, if everything is optional?
Similarly, I kept saying it for long that a file/wire format's usefulness is not in what it supports, but in what it forbids. A binary file supports any type of data, but it's not useful.
Having written a few RISC-V cores, worked on a chip design project that used RISC-V cores, and generally being OK with the architecture in real-world use cases:
What the heck is this guy's problem? Just about every thing he mentioned as a problem is not a problem in practice. Too many options? Who cares, you're not trying to write code that runs on every possible configuration. Either you're writing embedded firmware and know exactly what core you're using, or you're writing an application that runs in an operating system and that system has a minimum ABI like RVA20 or whatever.
Array accesses take an extra instruction? Either you're in a tight loop walking a tiny array and you don't do the full offset calculation per step, or you're walking over an array in RAM and you're bottlenecked by the memory bus.
Hell, 90% of his arguments are "You can't detect X at runtime from user code without relying on some extension" - Yes, that is totally fine. Either you know your target CPU, or you don't - and then you ask your OS for details. This is not some dealbreaker.
From the article - "For example, if you are writing a kernel and want it to support all RISC-V cores" - NOBODY IS DOING THAT. You target a platform spec, not the combinatorial explosion of everything from RV32E to RVA22 or whatever the latest is.
You want to distinguish S mode from M mode? WHY DO YOU NOT ALREADY KNOW THIS?
Instruction encoding is weird? WHO CARES, the decoding is like eight lines of Verilog.
"Who can predict how their binary will act when a floating point store silently becomes a double-register move or a jump instruction, or vice-versa?" - THIS DOES NOT HAPPEN IN PRACTICE.
Guhhhhh, I don't get it. This guy has some vendetta and either has not shipped any risc-v code or is just in love with his own personal favorite instruction set.
Yeah the OP post read to me like someone throwing the baby out with three drops of bath water. If this was presented more like “minor gripes with risc V” I’m guessing I wouldn’t feel that way
It has an effect only in terms of how big an offset you can encode in a relative jump, the _arrangement_ of those bits in the instruction is irrelevant (and already abstracted away in the compiler/linker framework).
> Array accesses take an extra instruction? Either you're in a tight loop walking a tiny array and you don't do the full offset calculation per step, or you're walking over an array in RAM and you're bottlenecked by the memory bus.
I'm not a hardware person, but whenever I look at compiler output I find computed index accesses all over the place in the assembly. This would suggest to me that at least compiler developers believe these addressing modes to be important.
> Yes, that is totally fine. Either you know your target CPU, or you don't - and then you ask your OS for details.
So then my code has to choose between being hardware-dependent or OS-dependent? That doesn't seem ideal.
> "For example, if you are writing a kernel and want it to support all RISC-V cores" - NOBODY IS DOING THAT.
I'd hate to live in a future where linux distros need to ship a separate kernel binary for every random combination of RISC-V features. That said maybe the run-time feature-detection extension will be so widely supported in practice that this wouldn't come up?
Either you're writing embedded firmware and know exactly what core you're using, or you're writing an application that runs in an operating system and that system has a minimum ABI like RVA20 or whatever.
It's very common for embedded teams these days to support a diverse set of cores with a shared codebase, depending on the specific requirements of different products/systems. SoC vendors will often change cores between versions or product lines, and I might need performance in this one system vs specific interfaces in another. So even if I know what core I'm using today, I don't know what core I'll be using in a year or five. I may also be writing a library or other reusable component and have no idea what core will run things today.
Array accesses take an extra instruction? Either you're in a tight loop walking a tiny array and you don't do the full offset calculation per step, or you're walking over an array in RAM and you're bottlenecked by the memory bus.
Let's take the bitfield instructions the author complains about for similar reasons. If bfi/bfx takes multiple instructions, optimal structure packing isn't necessarily a win for performance or memory usage. The programmer needs to trade off how often the structure is instantiated vs accessed. Even they can make the right decision today, it might not be the right decision tomorrow. And if they get it wrong, that might not be apparent until later (when it will be somewhat obscured in superficial memory usage analysis). Or the ISA can get it right the first time and also make things easier for compilers/humans in the process.
"Who can predict how their binary will act when a floating point store silently becomes a double-register move or a jump instruction, or vice-versa?" - THIS DOES NOT HAPPEN IN PRACTICE.
I can easily imagine this happening. When you change embedded platforms, the typical approach is to take the existing system and compile it for the new platform without carefully revisiting every decision made in the old system. If one of your vendor blobs was specified for the old system and the new system is "similar", you'll just link it in and see what happens. The metadata in the blob will hopefully catch the issue at link time, but it was an avoidable error.
Then it crashes in a nice, obvious way as soon as you execute one of them? Illegal instructions aren't usually that hard to debug unless they're related to memory safety issues.
Then you take an illegal instruction exception, and you have a choice to request a rebuild, patch it, or emulate it. (Yeah, sometimes the vendors just don't cooperate.)
Incidentally, emulating opcodes is quite often practical (unless the performance must not be affected), and is greatly helped by having the plainest, cleanest instruction encoding possible, and a well designed system register & exception architecture.
This guy is weird: there is no perfect ISA, only compromises and tradeoffs. He is looking for _his_ perfect. Won't happen, unless lucky, namely your perfect aligns with RISC-V tradeoffs. There are also sweet spots, and I am writting RISC-V assembly almost every day and that "hits" them often. I currently use at 99.99% the core ISA (I have a few muls and divs here and there). I don't even use the bit manipulation extension...
There are millions of RISC-V chips out there. Performant microarchitectures are getting there, but the access to the latest silicon process is gated by the other ones, hogging production capacity (and they probably don't want RISC-V to "get there"...).
And most of all, hardware manufacturer/designers won't have a lawyer ringing at their door: this is so much critical, this will make them tolerate a lot of RISC-V tradeoff choices they dislike.
And ofc, big mistakes WILL BE MADE AND WILL HURT BAD. Expecting anything else is thinking like a teenager.
It seems the current biggest mistake is the compressed instruction extension. It seems the complexity it adds for high performance is not worth it (arm removes the thumb instructions for reasons). I have suspicions on some microarchitectures designed around the compressed instructions (16bits) having a negative performance impact on core ISA 32bits instructions (and many compiler optimizations are friendly to the way compressed instructions are, namely the destination register is one of the source register, that due to the legacy x86_64). BTW, Intel APX something, is basically RISC-V for x86_64.......
Another aspect people tend to forget while dealing with RISC-V, many of those design choices were made for the simplest way to implement performant CPU microarchitectures. Some say thats why on 'out-of-order' CPUs, you don't want a status flag register (there is none in RISC-V).
So … use RISC-V as the strawman, and create a community-based RISC-6 that doesn’t have these weaknesses? Better to get in now before it becomes too solidly entrenched.
I mean, a shuttle run is pretty cheap these days. If you have silicon, and customers, scaling past a shuttle run that worked is pretty low additional cost.
You're vastly underestimating the amount of work that has gone into RISC-V that would need to be redone. It's not just a spec. There's an absolute mountain of software and hardware supporting it.
64-bit instructions with 4 bits indicating instruction formats (60-bit, two 40+20-bit variants, 30+30-bit, 20+20+20-bit, three 30+15+15-bit variants, and 15+15+15+15-bit). Have each larger instruction type be a strict superset of the smaller instructions, but with larger immediates, more registers, and maybe additional instruction formats (eg, for SIMD).
Something like that would be even easier to decode (converting short instructions to long is simply a bit of wiring). Instruction density should increase due to 20-bit instruction type. Having properly-aligned instructions would help with fetching performance. Larger instructions means you can jump 4x further with the same immediate and 16-bit offsets. No need to have some of the V extension workarounds (from not wanting to add 48-bit instructions).
Not traditional VLIW per-se as packets wouldn't imply parallelism (though that's theoretically possible) and instruction count would vary.
2-register to 3-register also just involves different wiring and costs nothing. I think you'd see 15-bit stick with 2-register. 20-bit would more interesting. You could choose to spend 3 bits on a third register or you could widen 2-register instructions to access the 32 core registers (or something between where you do 3-register, but only on 16 registers). 20-bit also reduces some of the need for very large 15-bit immediates (especially jump which is upward of 10% of the total space on 32-bit designs) which could allow more 15-bit instructions further improving effective density.
Easy access to 40/60-bit instructions mean stuff like vsetvli could simply go away and very useful instructions like FMA4 (instead of FMA3) could be added. Vector masking is another big one. They don't have enough bytes for a full vector mask set resulting in some hacks.
The big question is about jumping and predicting inside packets. You can add 2 bits for what externally looks like 16-bit addressing (where the 2 bits indicate packet position to jump to) or have faster jumps that always hit the beginning of the packet (at the expense of code density due to nops). There might even be a hybrid approach where short jumps can jump within a packed, but long jumps must jump to packet boundaries (which makes sense as most compilers make functions align on cache line boundaries anyway). There is a point for eliminating 20-bit (and all that compression goodness) for 45+15-bit pairs instead) as branches inside packets are immediately calculable.
One thing I noticed with your clever encoding is that you can avoid some nops: instead of having 2 15 bits instructions followed by two nops, you could have two 30 bits instructions, saving maybe a little decoding energy.
Also the 60bit format will really help for loading immediates..
That said I wonder why normal ISA do not contain a 'Load Immediate on Next PC'?
And if you want to allow parallel decoding the first byte of the immediate would be a 'special noop' and the first immediate byte would be inside the Load Immediate Next PC instruction instead.
I think this has to do with parallel decoding. How do you tell that the immediate is an immediate instead of an instruction? You have to carve out a very large part of the encoding space and you still can't fit a full immediate (eg, if you decided that all instructions starting with 1 were immediates, you'd be dedicating half of your encoding space to immediates and still be one bit short).
RISC-V does a 20-bit LUI (load upper immediate) then a 12-bit addi to the same register for the lower bits. Having access to 40-60 bit immediates makes 32-bit immediates a lot easier (with 64-bit immediates being multi-step, but quite uncommon).
> What does a cheap microcontroller core need? Let's inspect what they are used for. Typical use cases are to interface with and quickly reconfigure hardware blocks in a larger chip, eg in an MP3 player, an SD card, or a USB stick. The hard work is done by custom IP and the CPU core is just there to occasionally prod a register or configure something.
When writing a spec, every single thing you make optional, you split the possible implementations into two incompatible groups. Do this enough times and you end up with your spec being meaningless.
Things are generally defined by the neccessities that led to their creation. x86 was designed for home PCs and has been forced to evolve with PC technology. ARM was designed to take advantage of RISC architecture, and were forced to evolve with the mobile industry. What was RISC-V invented for, and what external forces have acted on it since then?
It's clear that RISC-V started as an academic exercise (albeit from a group with esteemed credentials) and they had to bolt on these hacks to make it work in industry.
ARM was also rooted in an academic exercise. A lot of the drawbacks for modern ARM PC platforms stem from the aversion to actually advanced features like SVE/SVE2 and UEFI.
It's sad, but it was also wildly successful. RISC-V has already replaced ARM in highly-custom embedded spaces like Nvidia's GPU controllers, and it likely won't stop unless ARM finally changes their tune vis-a-vis licensing.
"What range of offsets can a 16-bit instruction encode? Zero through three. Not thirty three, not three hundred and three. Three! Well, maybe it is better for storing a halfword? Nope... zero or two. What even? Why"
What the fuck is this criticism? Its sanely specced, who would want arbitrary unaligned offsets, like for anything? Supporting such obscure idiot cases is too much unnecessary pain, so cut it off on spec level
One of the things that drives me nuts about RV is the plethora of Zextensions. And on top of those, manufacturers add on their own proprietary extensions. That is one of the selling points. But...
Interestingly, in the Olden Days, machines often had custom instructions. The pdp-1/D had a tad instruction for 2's complement addition (it was normally 1's complement machine), and there were also new pdp-1 instructions for timesharing.
For the IBM 1401, there were all sorts of add on 'features', e.g. the Multiply / Divide Feature (sped up * and / in HW), High-Low-Equal Compare feature, Advanced Programming (added Index Register, Subroutine Linkage), Move Record feature (allows right-to-left movement until hitting a Record Mark, useful for Tape), Expanded Print Edit Feature (float $ sign, automatic * insertion, etc), various memory sizes from 1,400 characters up to 16,000 characters. The point is that manufacturer-distributed software had to deal with having features (or not); and this was handled e.g. in the assembler by having a CTL card that listed (coded) the features, e.g. "CTL 31110" says this is a 12K machine, with Automatic Multiply / Divide, the High-Low-Equal Compare, the Move Record Feature, but NOT the Expanded Print Edit Feature -- that told the Macro Generator what it needed to know to properly expand macros for a specific HW configuration. (Certain Features did not require SW mods, e.g. the notorious "Print Overlap" feature that would speed up print operations by having a hardware buffer to hold the Print Line, so the CPU did not need to stall. The feature was notorious because the sub-rack of HW required to implement it connected into probably 75% of the machine's instruction decoder & execution units; when it failed, it was incredibly painful to find the fault(s)).
And, there have been Writeable Control Stores like, forever. It was a feature on the Burroughs B1700, where different control stores could be loaded on-the-fly depending if you were executing COBOL or FORTRAN or Pascal - the 'instruction set' would be optimized for running that particular language. The pdp-11 had some version of this, and CMU's custom C.MMP had something like this.
So, the desire for certain customers to have machines specifically honed to their use cases was normal. It has only been this brief period of homogenization of single-chip(ish) CPUs (8008, 8080, Z80, 8086... amd64 etc) that introduced new instructions in tranches.
The End-Users now get their custom instructions in other ways (e.g. PCIe and GPUs)
RISC-V is... fine. It satisfies my two requirements for an ISA as a hobby CPU designer, which are:
1. Supported in mainline LLVM and GCC.
2. I can implement it without lawyers sending me a love letter.
Everything else, I can fix in post. There are enough good ideas spread across the extensions that I can assemble a reasonably put-together, curated embedded ISA with competitive performance and code density that admits a simple implementation.
I think Dmitry's points are largely on-target, though I have filed my usual statutory complaint that every rant that includes a bitfield diagram for the RISC-V J format should accompany it with a similar diagram for the Arm T32 BL encoding.
> RISC-V is... fine
Exactly.
> It satisfies my two requirements for an ISA as a hobby CPU designer...
You probably have some unstated requirements as well, such as available toolchains and "vetted well enough to actually be able to run code."
Risc-V now occupies the Schelling point for people who, for whatever reason (rent-seeking and security top the list) want to leave the x86 and Arm ecosystems.
They did explicitly specify:
> 1. Supported in mainline LLVM and GCC.
Which pretty well encapsulates the ecosystem requirements.
Luke is too modest. Something in the region of 5 million chips containing his hobby CPU have shipped since launch on August 8, 2024.
Could you share a link or more details? What is this hobby CPU project?
Luke Wren works at Raspberry Pi and designed the Hazard3 CPU core that is in the RP2350 chip.
I think the GP is talking about the Hazard3 [1] core. This is one of the CPU cores besides the ARM M33 instantiated on the RP2350 µC [2]. See this article from Luke Wren (Wren6991) back when the RP2350 came out [3].
[1] https://github.com/Wren6991/Hazard3
[2] https://www.raspberrypi.com/products/rp2350/
[3] https://www.raspberrypi.com/news/risc-v-on-raspberry-pi-pico...
Thank you!
What I find interesting is that RP2350 is designed as "one or the other", no way to use ARM and RISC-V concurrently, and has fuses that can kill ARM M33 cores outright.
Makes me wonder if an "ARM cores fused off, RISC-V only, no ARM fees" SKU is possible.
Several of the peripherals in the RP2350 are also ARM IP.
You can choose Arm in one pair and RISC-V in the other pair if you want.
RISC-V is in many aspects just legally-distinct-MIPS, from the base instruction set all the way up to how certain extensions introduce kludges that are very reminiscent of later MIPS additions. While I do somewhat agree on the fact it was a huge missed opportunity to improve upon MIPS's technical flaws in order to realistically compete against the likes of ARMv8, we still have to keep in mind that the primary driving force behind RISC-V is and has always been fixing the legal flaws instead.
There is indeed plenty of value to be had from a standardized (if poorly) PlayStation-1-era instruction set you can safely implement in silicon with no risk of a zombie company husk coming after you, especially in the ASIC space where (as Dmitry himself recognized) anything is better than an 8051 core you need a copy of Keil C51 and a lot of patience to write code for. Even if you end up having to add custom extensions, it still is a much better starting point than coming up with your own bespoke ISA, building a toolchain around it and convincing potential customers that your proprietary architecture is worth the effort to deal with over another vendor's licensed Cortex-M cores with full GCC and LLVM support.
Has it been proven that no patent troll holds a patent covering RISC-V?
Of course not because that's impossible to prove.
You might find this relevant: RISC-V Genealogy (2016) https://riscv.org/wp-content/uploads/2025/02/EECS-2016-6.pdf
Or in poster form: https://riscv.org/wp-content/uploads/2025/02/RISC-V-Instruct...
Yeah, very much legally distinct MIPS, at least as a starting point.
The biggest tell is the mnemonics. While RISC-V takes a bunch of ideas from other places, and cleans things up, it copies a lot of mnemonics straight from MIPS.
But it also copies a lot of other ideas from MIPS, like the absolute distain for flag registers.
>absolute distain for flag registers
It's worst aspect maybe.
The RISC-V specs insist that this is important for simplifying high performance designs, because a flag register is a single piece of shared state that instructions are constantly (and often inadvertently!) touching. This necessarily introduces hazards and serialization.
I don’t know enough about high performance microarchitecture design to evaluate that argument confidently, but it seems to make sense to me.
Inadvertent touching is fixable, ARM for example did it with the S bit (though on AArch64 it's slightly more complicated).
I regard it as a mistake of RISC-V. The flag register was invented for good reasons, and dropping it is a trade-off I personally do not think is worth the downside.
I don't agree with the argument.
By the time you have an out-of-order core, there is already so much shared state you have to synchronise, and you have a bunch of complex mechanisms for dealing with it. Adding a flags register doesn't really add any more complexity, it's just a small bit of extra state attached to it.
And we already have the solution, it's register renaming. We are already renaming all the GPRs and FPRs, and we are probably also renaming part of fscr (because turns out, RISC-V does have flags for floating point operations), maybe a few other bits of state. So we just use the existing renaming mechanism to rename a bank of flags registers; That single logical shared flags register is actually backed with a bank of non-shared physical flags registers, neatly solving all concerns.
Sure, the renamed flags do take up a bit of die space. But IMO they don't add any extra design complexity, and shouldn't have any performance impact on maximum clock speed.
RISC-V isn't quite as disadvantaged by the lack of flags as some might suggest (and I wouldn’t say the lack of flags is RISC-V’s worst aspect), but there are a few sequences (add-with-carry, some conditional-moves, detecting overflow) where RISC-V is forced to burn an extra instruction or two to deal with the lack of flags, and IMO eliminating that would be worth the cost of slightly more die space.
Also, avoiding the need for dedicated compare-and-branch instructions would free up encoding space for other things (including larger range on branches)
You're thinking too high level and high performance/high power use -- think about minimal embedded controllers, no need to add the complexity of O3 exe, but there's still the possibility of getting to optimize the hazards and execution without the shared state.
Doing the deliberate choice of leaving flags out of the core and then using them in the fp ops ext will nudge designers towards "this is probably the point you should think about out-of-order execution"
If the spec was only arguing that avoiding flags allowed for simpler implementation of minimal in-order pipelines... I might actually agree with it.
But the argument in the spec explicitly uses the "added complexity to out-of-order microarchitectures" as a part of the justification for not having conditional move (and flags). It's the most commonly parroted part of the argument (see above) and the part of the argument I'm responding to.
I actually agree with much of the spec's argument. The cost of not having flags is pretty low, the MIPS approach does work pretty well, and it does simply things.
I'm just not sure it was the right trade off, and I strongly disagree with its attempt to use OoO cores as part of the justification.
Without knowing it, you're thinking at neither high nor low level. You've accepted at face value claims made by RISC-V architects about how to design an ISA for low level embedded controllers, but they weren't actual experts in that field. Instead, they were largely academics.
When you read their stuff, they're constantly overestimating the value of ultra-minimalist CPU designs in the modern context. In fact, they often show little understanding of the real impact of ISA design decisions on implementation complexity, so some of their decisions don't even make sense as minimalist decisions.
To expand on the low value of minimalism: even in trailing edge process nodes, if you're designing something on the scale of a simple single-issue in-order 32-bit RISC core targeting no particular frequency, gates are essentially free. The RISC-V guys are badly out of touch. If minimum gate count mattered as much as they think it does, there would still be a thriving market for 8-bit microcontrollers. Instead, they're steadily losing market share to 32-bitters, even in applications where an 8-bit µC would be more than enough. It's not the 1980s, you don't have to struggle to fit a featureful 32-bit core into a single die anymore, but they're hellbent on relitigating that era's debates.
> Adding a flags register doesn't really add any more complexity, it's just a small bit of extra state attached to it.
I agree in general, we do however see that the cost of flags isn't free by the fact that most modern Arm processors only support ADCS on half of the ALUs supporting ADD. If it was free/negligible, you would see ADCS support on all ALUs.
Yeah... I more mean that it shouldn't add much design and verification complexity. You are mostly just reusing mechanisms you already need. Nor should it negatively impact FMAX. And I suspect the area cost is reasonably low (but not zero)
The lack of flags on those ALUs probably tells us more about the lengths CPU designers will go for reasonably small savings than it tells us about how much flags actually costs. And it's probably more of a "our metrics never gave us enough justification to even consider adding flags to the extra three ALUs" than "we considered it, but the cost was too high".
> Of course not because that's impossible to prove.
Why?
It's supposed to be impossible to prove a negative. But it might still happen some day. We just don't know.
"it's impossible to prove a negative" is a simplification. A negation is just the oppositive of an affirmation. If the affirmation is "there is an element E of an infinite set S that satisfies property P", the negation would be "there is no E in S that satisfy P", which would make proving by enumeration require checking every element of an infinite set, which is impossible. But other forms of proof might be possible.
The set of US patents, however, are not infinite and, IIRC, is also public. That said, IP laws are a mess.
It was a joke I think.
Someone might also file a new parent, then apply it against RISC-V. You'd think that wouldn't be allowed to happen, and maybe it isn't, but only an expensive lawsuit will prove it
Given the nature of the US legal system as based on common law, that applies beyond patents, and may affect ARM and x86 as well. In the end, the real, effective law is the one understood by judges, adjucated in court cases, built on precedents.
That being said, I don't expect someone filing a new patent after a RISC-V extension being published to last much longer beyond discovery in most cases, which should keep costs in lower end. Specially so in cases of bad faith.
Well played
Patents only last 20 years.
If you build your architecture on ideas that are documented to be older than twenty years, it greatly reduces the risk that a patent holder comes from nowhere: even if they did have the patent, it would have expired.
How quickly does the industry move? Would there be any value in a 2006-era instruction set? How would you even start making sure you didn’t infringe on any patents that came after 2006?
The first version of RISC-V was released in 2010. It was based on work done at Berkeley in the 1980s (RISC versions one to four).
One reason that RISC-V has so many optional extensions is that you can trust the core is very likely to be patent-free (because everything in it is documented to be older than 20 years) and just evaluate the extensions you need.
If you iterate trough every concept RISC-V has, you might be able to prove it.
The RISC/MIPS concepts date back over 40 years. The base instruction set is intentionally designed with unencumbered, expired, or public-domain architectural concepts.
RICV-V microarchitectures and implementations are at much high risk of violating patents. Especially anything that is even slightly high performance. SiFive, Andes , and Alibaba’s T-Head are filing thousands of patents on microarchitectural optimizations and extensions. China's RISC-V patent-sharing alliances and other industry groups are building defensive patent cross-license around their RISC-V-related patents.
> it still is a much better starting point than coming up with your own bespoke ISA
5 years ago I would have agreed with this but now I'm not so sure. We live in an era where you can tell a robot "Here's some C code. Design a 64-bit ISA, write the Verilog to implement it in an FPGA, write a C compiler for it, and use it to compile the C code I showed you earlier."
And now your ISA and your compiler are part of your moat. I can just see the VCs salivating.
Coming up with any ISA and coming up with a good or better ISA are two very different things.
If that's really all it takes, then it is not much of a moat.
In the set of all possible working implementations, there are one or more that are novel enough to become a moat legally or otherwise. If everyone has the same power (number of tokens) then capability (experience and understanding) becomes the differentiator to “find” that moat first.
If everyone has equal ability to build a moat, it's not a moat.
If every one has a hammer and a saw and identical wood planks, everyone can build a frame that holds up 100 years?
Think it through. This is the HN comment section after all.
Designing a good 64-bit ISA, much better than RISC-V, is easy.
There are thousands of people who could design such an ISA in a couple of weeks, without any AI assistance.
The hard part, which has always been the moat of RISC-V, is writing all the required support software for a new ISA, i.e. all the utilities from binutils (assembler, static linker, ELF/DWARF utilities), compiler backends at least for gcc and llvm, debugger (at least a port for gdb server), dynamic linker and standard C library, possibly some parts of the standard libraries for other programming languages.
Previously this could have taken years and it is the only reason that has always justified the choice of RISC-V for minimum cost, despite how bad the ISA is.
If today the porting of all these software support applications to a new ISA could be accelerated with AI assistance from a couple of years to a couple of months, that would certainly enable the design and use of custom ISAs, and RISC-V would lose its appeal.
The effort to support architectures is now minimal with AI assistance. I made a hobby architecture (based on Intel, but with some changes; I was making an "alternate history" as if a few decisions in the past had been different) and it was pretty much trivial to spit out support not just in gcc and llvm, but I also, for fun, made WATCOM backends and a few other things.
With that said, RISC-V is a nice baseline for designing another architecture. Start with RISC-V, and go from there.
> and it was pretty much trivial to spit out support not just in gcc and llvm, but I also, for fun, made WATCOM backends and a few other things
No links? You may have dreamt about it instead.
The main difficulty in support isn't actually making the changes (which is going to be largely defining various tables and other boilerplate, unless your ISA is really weird and does something unusual), it's in doing all of the politics necessary to get those changes committed upstream.
Maintining this type of long time fork is the kind of mind numbing, tedious thing LLMs are actually exceptionally good at. I did some backend work on Lean4 compiler and then they switched out parts of the codegen, it took Codex less than an hour to recover the feature set I had implemented but on the new backend.
> Designing a good 64-bit ISA [...] is easy [...] could design such an ISA in a couple of weeks
Let me know when you've got it all worked out and published. Should be easy, right?
It is the easy part. Four weeks is plenty of time.
That's why it's so bizarre that the RISC-V design is so awful.
The hard part is the software support side (though, as comments elsewhere in the thread point out, AI is pretty helpful there) and then those lovely pieces like specifying the precise behavior of interrupts.
If it had a snowball's chance in hell of going in to any kind of production anywhere, I'd have no problem spending the next month laying out an ISA. But, again, as this thread makes very, very clear: ISA really just doesn't matter.
> That's why it's so bizarre that the RISC-V design is so awful.
Not bizarre.
The design is a direct result of the biases of its initial designers, and its original intended use-case. And TBH, if you assess it by its original design criteria, it's actually pretty good.
It's just by the time RISC-V had escaped containment and was starting to become a general purpose open ISA, it was a little too late to start from the beginning and consider what the correct design criteria should even be.
Very true... but I can't help but note that basically every person I've ever met with significant experience with multiple architectures at this level, and not connected in some way to RISC-V, utterly hates the thing.
That feels like a "don't release yet" flag to me!
But I hear you.
It looks an awful lot like something that was designed by a sizeable committee made up mostly of academics, most of whom won't have written ten lines of code in as many years. I don't actually know in this case, but I've had to sit and watch standards created in this manner, and Dmitry's description of the RISC-V mess matches their output fairly closely, a chaotic mess that includes every idea everyone on the standards committee has ever had, all made optional so no-one will vote against it when it comes to balloting.
How many people are working on this in your couple years example? Is that just one guy or a team of 20 or something else? Whats the average salary for the team *n this scenario?
I said "me" and "four weeks" because laying out an ISA is a pretty straightforward job for one person in one month.
The deliverable would be a (theoretically) complete specification PDF like RISC-V's.
I have little doubt that I or Adrian could do it, or plenty of others. It might not reach the quality of something like AArch64 with that level of resources, but it's not hard to beat RISC-V.
That's why I've never understood the point of RISC-V. Anyone can design a (reasonably OK) ISA. It's everything else that's the hard part. It's like announcing a new house, it's going to be pained Benjamin Moore Yellow Oxide and everything else is someone else's problem to sort out. Success! We've got a new house!
The only argument I've ever seen for RISC-V that's vaguely logical is that there's no licensing to Arm involved, but since I can get M0/M3 devices for a dollar or so with infinite tool and library support that's something that's totally irrelevant for most users. And if I don't mind going with Chinese suppliers there's no licensing to Arm being paid anyway.
Apart from being able to thumb your nose at Arm, I just can't see what the point of RISC-V is. Is that really all there is going for it?
> The only argument I've ever seen for RISC-V that's vaguely logical is that there's no licensing to Arm involved, but since I can get M0/M3 devices for a dollar or so with infinite tool and library support that's something that's totally irrelevant for most users.
How expensive is it to license the instruction set so you can expand it?
Surely those expanding the instruction set do not fall into "most users"?
Dunno, I'm still saving up for the billion-dollar fab I'll need before I can think about licensing an instruction set.
As an aside, Espressif (or Xtensa if you want to split hairs) have been quietly doing a lot of what RISC-V is supposed to do for years now. I know they've also been fiddling with RV32's but all the real work is LX6/LX7. They're best-known for their use in ESP32s but they also crop up in an awful lot of industrial/commercial gear.
How is that a moat, if anyone else can do the same thing?
And how would you get this all into Clang? Nobody wants to use your custom compiler. It's certainly not going to be as fast as Clang!
it still is a much better starting point than coming up with your own bespoke ISA, building a toolchain around it and convincing potential customers that your proprietary architecture is worth the effort to deal
There are lots of somewhat successful yet little-known Chinese companies with their own proprietary architectures and the toolchains to match, so I don't think it's that clear-cut. (That said, most if not all of them are somewhat MIPS/RISC-V-ish anyway...)
I do think 8051 is better when you don't need 32 or even 16 bits. Even 4-bit MCUs are still around in ultra-low-cost ultra-high-volume products, which is to say RISC-V is, as you said, just a different flavour of MIPS with very similar tradeoffs.
Google search turns up LoongArch (RISC), Shenwei (CUDA-like, HPC), UniCore (RISC). ESP32 is using Tensilica LX6/LX7 RISC base (RISC designed for custom hardware extensions).
C-Sky and Andes NDS32 were popular enough to be supported by both GCC and the Linux kernel, both switched to RISC-V. ESP32 switched to RISC_V for all new chips.
Interestingly Synopsys's ARC's latest version ARC-V is RISC-V.
I think all major FPGA vendors now offer fully supported RISC-V soft cores either alongside their older proprietary ISAs or as the latest upgrade. Several (e.g. Microchip and Gowin) have included real RISC-V cores inside FPGAs.
China is different - the state probably has impact on cpu/mcu vendor selection.
All states regulate, subsidize, or otherwise exert influence on companies acting in their territories. China is not unique or different in that regard. They have been forced to try somewhat harder, but that was really due to the actions of the US trying to restrict their access to free trade. Chine restrictions on buying western tech didn't come until far after NATO countries had placed similar restrictions on Chinese tech.
You can’t fix the mutually incompatible overlapping encodings in post.
Practically you don't simultaneously want those overlapping encodings.
They actually did do that. C was split into ZcfZcdZca, so you can choose a non-overlapping subset. It doesn't affect an RV32 non-F core anyway.
I… you can’t be serious.
Yes, I'm serious. I think the overlap is an aesthetic problem rather than a practical one, given that:
* The profile used by "Big SoCs" already explicitly depends on F + D + C, implying ZcdZcf, so the newer Zce won't be implemented.
* The compressed float load/store opcodes repurposed for Zce are often unimplemented on embedded processors.
* The ELF file has an attribute section telling you the exact ISA string. If you're debugging an embedded system you probably depend on the ELF file anyway for DWARF info as you likely don't have frame pointers.
If you disagree then that's ok, I'm happy to be disagreed with, but please explain.
In x86 land, there are, as a practical matter, four ISAs: real/v8086 mode, 16-bit protected mode, 32-bit protected mode, and 64-bit “long” mode. Machine code targeting one of these will be executed correctly by the CPU as long as the CPU is in the right mode. (Really it’s messier — there are the CS.D, CS.L, and SS.B bits plus the control bits for v8086, protected and long mode, but this barely matters.)
Sure, this is messy. But, critically, on x86, these are all modes, and any CPU that supports them makes them detectable and supports them in the same way. If you run long mode code outside long mode, some opcodes will be interpreted as the wrong instruction. But you will not find multiple different CPUs that decode valid instructions differently. If I run your weird old x86 code, either it will run correctly or it will fault.
Oh, and all these modes are older than RISC-V. To the extent that there are lessons to be learned, RISC-V should have learned them.
The fact that you can apparently find two RISC-V CPUs that decode some ordinary user mode instructions based on published standards as entirely different operations is bizarre, to say the least. The fact that the relevant CPU features can’t even be enumerated in user mode just makes it worse.
(There are edge cases in x86. Some invalid opcodes have different lengths on different vendors’ CPUs. This is not a problem in practice because, one way or another, they fault. There was also a little glitch in the 64-bit design where some really really old x87 FPU code that uses exceptions cannot be corrected handled by a kernel on a modern CPU.)
> The fact that the relevant CPU features can’t even be enumerated in user mode just makes it worse.
User-mode feature detection is usually used to select paths for acceleration instructions, like SIMD or crypto. The overlapping RISC-V instructions don't fit in that category: they're compressed versions of basic functions, mostly used in epilogs/prologs, which would be unconditionally compiled in.
There are no overlapping encodings in the 32-bit encoding space and I'm really hoping it stays that way.
> To the extent that there are lessons to be learned, RISC-V should have learned them.
Yeah, I think I agree with this. Also I wish I had been there when Andrew Waterman was writing his master's thesis so I could ask him not to include Whetstone in his size benchmarks, so that we might have left that encoding space free and avoided this conversation :-)
At least with user-mode feature detection there could be an assertion that the correct feature set is present.
Doesn't the ELF loader do that?
> But you will not find multiple different CPUs that decode valid instructions differently. If I run your weird old x86 code, either it will run correctly or it will fault.
Oh, that's not completely true. Intel 64 and AMD64 are not identical and they certainly have encodings that behave differently. As an example: f3 41 90 is pause on Intel, but xchg r8d, eax on AMD (granted, this is not a canonical instruction encoding). 66 e9 xx xx yy yy is a unconditional jump to a 32-bit relative offset on Intel, but on AMD, the offset is 16-bit only (yy yy are the start of the next instruction). x86-64 is typically used to refer to the very large common subset, but this doesn't mean the implementations behave identically.
There are also some weird corner cases where CPUs aren't 100% backwards compatible, just backwards compatible enough for the software that matters.
For those less familiar with x86, the example instruction encodings that are interpreted differently on Intel and AMD are not base encodings, but instruction encodings modified with prefixes.
The x86 ISA includes a great number of bytes that are used as instruction prefixes, many of which are obsolete. The problem is that the effect of prefixes upon instructions has never been completely defined in any Intel or AMD documentation. The prefix effects have been documented for some instructions, but they were left unspecified for most other instructions.
This has lead to divergent implementations in the unspecified cases. Well-behaved compilers should not generate such undocumented combinations of instruction prefixes with base encodings.
> The problem is that the effect of prefixes upon instructions has never been completely defined in any Intel or AMD documentation.
In case of the jump example, the effects are documented by Intel and AMD and they still differ. Point of the GP was that all CPUs don't decode valid instructions differently, which is not fully accurate as shown by the examples; and some of these differences are also explicitly documented.
It's also not accurate that most prefixes are obsolete when most see regular use today (66 size override for 16-bit operations, f2/f3 for string operations, 66/f2/f3 mandatory prefix for many (e.g. SSE) instructions, 64/65 fs/gs override for thread-local storage access and per-thread kernel storage, f0 lock for atomic operations, 3e (again) for branch-taken hint, 4x REX prefix for r8-r15 and 64-bit operand size; one can argue that the 67 address-size override is useless, and only the 26, 2e, and 36 are ignored; I don't count VEX/EVEX/REX2 as prefixes but more as opcode escapes).
Fair point.
66 E9 is not a practical compatibility problem, though: it’s not a useful encoding of a useful instruction on any CPU :)
> There are edge cases in x86
Some early 386 CPUs had XBTS/IBTS instructions (extract/insert bit string). They used 0F A6 and 0F A7 encodings.
Some early 486 CPUs had CMPXCHG encodings that reused the XBTS/IBTS encodings. That apparently screwed up some programs that tried to execute XBTS/IBTS to see if they were running on early (buggy) 386s so Intel moved CMPXCHG to different encodings (0F B0 and 0F B1).
0F A6 and 0F A7 are still left unused by Intel and AMD in their modern chips.
There's also the delightfully petty story about SYSENTER/SYSEXIT and SYSCALL/SYSRET for fast system calls. Intel came up with the first pair, AMD with the second. AMD of course had to support both and operating systems generally only supported Intel's pair.
Then AMD extended the x86 to 64 bits and of course required SYSCALL/SYSRET for 64-bit system calls (and did not support SYSENTER/SYSEXIT in 64-bit mode). Intel had to support AMD's instructions in 64-bit mode but decided to also support SYSENTER/SYSEXIT there (which I don't think any operating system has ever bothered to support).
To summarize: AMD supports both methods outside of 64-bit mode and only their own in 64-bit mode. Intel supports both methods in 64-bit mode and only their own in 32-bit mode. Or at least that's how it used to be. Maybe they've mellowed out by now.
Oh I remember SYSENTER/SYSEXIT, I think. I worked on CTOS, widely released by Burroughs/Unisys back then. CTOS used all the clever instructions. They performed badly. Later I learned from an Intel customer consultant on porting code, that we were the only ones who ever embraced fancy things like task gates etc. Everybody else just continued using regular push/pop and simple traps. Because they ran faster.
Yes, but x86 had a goal of running every old piece of code on the new thing. That’s not true with RISC-V. Whereas x86 accreted more and more features, RISC-V solves this with profiles that are not guaranteed to be compatible with each other. RISC-V doesn’t even support running 32-bit code on 64-bit processors without a recompile. In a sense, 32-bit RISC-V is a vaguely similar but incompatible ISA to 64-bit RISC-V. That would be a train wreck if there weren’t profiles to specify a group of features that must be there (and some others that might be optional, with a register to flag whether they are or not). The expectation is that profiles act a lot more like the x86 ISA, accreting features while preserving backward compatibility. It took me a while to realize this, too, and I remember several WTF episodes while reading through the specs. And of course profiles go beyond the ISA and specify system level arch as well (like the “PC architecture” did for Windows and Linux). You can certainly argue that it should have been done differently, but it’s not completely crazy given that there is not legacy RISC-V code needing to be run on newer systems for the most part. That won’t be true forever, and so profiles help manage that.
There is a lot to unpack, hence my reaction. Instead of a straight compressed instruction format supported (or not supported) everywhere, we get an alphabet soup of options. C -> "ZcfZcdZca" just by itself is insanity. But the actual technical change is a problem too. Now I can't make vendor-independent RISC-V code, since apparently they all support different compressed instruction sets.
I represented my company as a founding member of the RISC-V foundation. I now shake my head at what it has become and hope I never have to write code for a RISC-V system again. Every time I check in it seems like some new insanity has manifest itself.
> C -> "ZcfZcdZca" just by itself is insanity
Separating the float load/stores from the rest of the compressed ISA is insanity? Why?
> Now I can't make vendor-independent RISC-V code
I think this is what RVA23 is for. Any system running shrinkwrapped binaries is going to have vanilla RVC.
I agree there is some insane stuff going on in RISC-V. Like when the double-trap spec was in public review I popped my head in to say "hi, this seems to break all existing code that uses nested interrupts because the condition is overly broad" and the spec maintainer said words to the effect of "yes, it's supposed to do that."
This is not that weird, though? Float load/store should never really have been included in the C extension, but we can't revise the C extension. So, define an extension for "C: the good parts", aka Zca, and separate extensions for float load/store (two of them because F and D are separate). Ideally we wouldn't have made the mistake in the first place, but what would have been a better way to redact it?
Not redacting it would have been better. Either live with it, or you explicitly create a new incompatible ISA. What happened is the worst of both options.
Sure can. Just change the encodings.
You thought RISC-V chips were compatible with each other beyond the basics? They're not. RISC-V is only a starting point for designing the ISA your chip will actually implement. Don't get me wrong - it's still beneficial that simple code works on many chips.
HP wrote a JIT to migrate old applications to their new hardware. So did Apple, twice. I don't know if IBM were the first but they've done it a few times as well for their mainframe hardware.
In HP's case, they tried running their JIT to translate from architecture B to architecture B and ended up with better performance than running it directly.
HP or HP née Compaq née Digital Equipment Corporation?
HP proper. It was a PA-RISC they were targeting.
https://cseweb.ucsd.edu/classes/sp00/cse231/dynamopldi.pdf
HP also used a binary translator to migrate from HP3000 to PA-RISC in the 80s.
100% agree. Is it ideal? Nah. Can you launch successful products with it with only a moderate amount of headache? Yep!
Heart of our system that powers a household name devices is a RISC-V multi-hart SoC. It does quite a bit - a little bit of compute, a little bit of DSP. Definitely not the best fit, but cheap and works well enough. The buggest gap for us was the lack of the decent debugging featurea like ARM's Data Watchpoint Traces - but maybe there is an extension for that already?
I'm guessing you're using one of RISC-V ESP32 variant (ESP32-C3?)
Nope, that is a custom SoC that had SiFive RISC-V cores from the times when they still did embedded stuff.
>2. I can implement it without lawyers sending me a love letter.
What's stopping them? They can trivially claim it infringes any number of patents...
This is a good point, and of course this is why IP lawyers are so important: they protect you from other IP lawyers.
> RISC-V is .. fine.
Yeah, so was 8051 and it sucked too :-). I appreciated having this rant all in one place. Ranting against bad architecture is always cathartic and absolutely useless since the people who built and now champion the bad architecture are invested so one's rant simply irritates them. And like the parent comment here, I too find RISC-V "useful" in that it has sufficient tooling to make most everything foundational 'out of the box' rather than me having to build it.
Perhaps the most interesting thing is that RISC-V shows just how ISA agnostic people are, as long as you have cross compilation with the gcc suite and an open source way to program and debug things. Before RISC-V, working on a bespoke ISA and computer architecture was never going to "go" anywhere except perhaps into a paper or conference talk. Now there is evidence of a non-zero chance of it going mainstream. :-)
> Perhaps the most interesting thing is that RISC-V shows just how ISA agnostic people are
To the extent that Raspberry Pi shipped a microcontroller that can literally be either RISC-V or ARM (indeed, one of each at the same time I think?)
RISC-V, it seems to me, lives in that cognitive space occupied by things like: open source, open weights, C, HTML, ethernet, Greggs sausage rolls and VHS.
Far from optimal, obviously flawed, and could change human society for the better. Ubiquity is inevitable.
Not sure why you had to take a pop at Greggs there. Nothing wrong with a hot sausage roll at all. Assuming you can find a hot one.
you should review the data on processed meat. It's one of the least healthy things you can eat.
Do Greggs sausage rolls even contain meat?
There is a meat option
Is there a named meat option?
What’s far from optimal about open source? Open source seems like a window into another universe, which is just lightly better than ours: people just working on problems and sharing solutions, because humans are basically good social creatures that enjoy solving problems. To the extent to which there are issues like the difficulty of funding open source projects: our society is wrong, not open source.
> Perhaps the most interesting thing is that RISC-V shows just how ISA agnostic people are
Of course! Most people in the computing world work way higher up the ladder of abstraction. I suspect a small minority of working software engineers know what an ISA even is.
I did some contract work in web development for a time. It is staggering how few people understand how the javascript they write gets executed on the machine. People don't understand pointers, or virtual machines, or in many cases how JS bundlers work, despite using them daily.
In some ways, this is a sign that our abstraction layers have been a great success! People can program for the virtual javascript machine, without needing to understand how the actual machine works, or how it emulates javascript. Is this the future we wanted? I'm not sure. But it's here.
What's next? Programming Javascript without understanding Javascript??
That's not next...it's now. Through at least LLMs and languages that compile to JS.
Definitely. I’m a weird software guy that got a hardware degree in college so that I could understand all the low level stuff. I remember there was a joint project with the hardware (ECE) and software (CS) students to build a simple computer with bit slice and microcode and program it to do something (I forget what). I remember the software students being bewildered that there was no division instruction in these systems (because who needs that when you have shifts and add/subtract). Nowadays, with so much stuff running in browsers, the average software engineer has no clue what the hardware is doing.
Nobody wants to cross compile a full linux OS though just for their project. I assume most are using debian multiarch (as they do for arm), and that does mandate a common RISC-V ISA subset. So presumably this will drive further standardization
> diagram for the Arm T32 BL encoding
is that... bit xor?
did they attempt signed immediate, but gave up 3 bits into a 32 bit immediate?
wtf
It originally had a range of 4 MiB, and they extended it to 16 MiB in a later ISA revision. The bits with the XORs were originally constant-1 and they wanted to keep backward compatibility, so bits J1 and J2 are interpreted as "if this bit is clear, toggle this position in the leading sign bits".
There is very cool history as to why. In armv5 the BL was two separate instructions. You could take an interrupt in between. And it was documented what each did. Veeery cool. Then they wanted more range. And now that they redefined the two halves as one instruction that could not be in halves, they also redefined a few bits that were always 1 before, to allow the second half of the instruction to be recognized right without a “previous instruction was first half of BL” flag somewhere that would need to be context switched and all that.
My disagreement with the article is mostly the following:
RISC-V is not an ISA, but an ISA generation framework.
If RISC-V would've standardized aarch64 1-to-1, the end result would've still been a huge extension mess, because a lot of people (RVI member) have different requirements and a very happy to build their own subsets, which would then be upstreamed because multiple vendors want the same subsets and compatibility between them. Obviously it would've been better, similar to if RISC-V spawned with RVA23 done, but development takes time and RISC-V International started, because people where already using RISC-V.
RISC-V also is the most DOSed ISA, with people proposing crazy stuff. Just the other day somebody proposed an instruction that would do up to 2^30 16-bit comparisons in one instruction at the largest VLEN. Because they wanted to improve their string processing usecase.
---
In my experience RVA23 matches aarch64 and x86 in uop count (without fusion), code density is better, instruction count is slightly higher. The biggest impact on the instruction count advantage of aarch64 over RVA23 is a single instruction, load-pair, which gets cracked at decode in every high-performance implementation, because it writes to to registers.
The Arm approach to code density is using multiple writeback instructions that have to be cracked and the RISC-V one is RVC. Both prohibit simple linear scaling of parallel decoding, so code density seems to have mattered to Arm enough to make the tradeoff worth it.
wdym by "gets cracked at decode"?
The decoder decodes them into two or more internal instructions (uops).
Take for example a post increment load, which does a=mem[b++], notice how this writes to two registers. Handeling two writes (up to 4) would explode the stage after decode (rename). So high performance arm implementations generate two uops for this. But since the number of decoders is fixed and the number of rename slots as well, you now have alnost the same problem as in RISC-V with compressed instructions: the nth input to the rename stage can come from a variaty of outputs of the decode stage, so you need a large shuffle network, and propagate the uop counts from start to end.
Cracking is a lot cheaper, if you can do it later in the pipeline. E.g. the cheapest is if you can simply "replay" the instruction. That is, instead of removing the entry from the issue queue, when it starts executing, you decrement a counter and keep the entry to do something else next. But as I mentioned that doesn't really work with multiple write back.
A lot of CPUs does not execute instructions directly, but instead translate them into a second set of "uOps"
This allows it to split complex instructions into multiple operations instead of having dedicated hardware for it.
High performance cores can also do the opposite trick of "fusing" two instructions into a single uOp: The usual example is compare-and-branch
> What does a cheap microcontroller core need? Let's inspect what they are used for. Typical use cases are to interface with and quickly reconfigure hardware blocks in a larger chip, eg in an MP3 player, an SD card, or a USB stick. The hard work is done by custom IP and the CPU core is just there to occasionally prod a register or configure something.
This is not the only reason to use a microcontroller or 75% of microcontroller vendor (e.g. STM) offerings would have no customers. Not everyone has custom IP that does all the work either, that’s actually fairly rare. It’s odd to pigeonhole microcontrollers like this just to go on a fairly lengthy rant about interrupt latency as if that somehow makes RISC-V unsuitable to what is an incredibly diverse application space. Maybe the rest of their post has better arguments, but I’m not impressed enough by the first one to keep reading.
This is a "microcontroller core", not a "microcontroller".
We're talking "deep embedded" applications - where an ASIC is designed for a very specific purpose, and that design just so happens to call for a programmable CPU core to be included in it.
This is the kind of design that lives in your keyboard, your mouse, your USB stick, your USB hub, your HDD, your SSD, your eMMC chip, your memory card and more. Remember: you're never more than 3 meters away from an 8051 core.
I do agree that most of this piece is nitpicking - poking at ultra low level things that are largely irrelevant to the tried and true "deep embedded" exercise of Just Ship It.
No one really gives a shit if an operation takes one instructions or two, or which instruction sets are consistently present in different cores. What "deep embedded" people give a shit about is not having to work with ancient 8051 tooling and 8 bit ALUs and memory banked 64kb spaces while writing code for the one core they happen to actually have. And RISC-V got that. The piece actually agrees with that sentiment.
By volume, I would expect the majority of microcontroller silicon shipped to be these kinds of deeply embedded cores. They even show up in chips called “microcontrollers.”
Å microcontroller needs a microcontroller core.
EDIT: Leaving that Å in. For some reason, iOS on iPad is obsessed with autocorrecting "A" to "Å" even when using the English keyboard. It's driving me nuts.
That autocorrect business would be a great modern technology prank to do to someome on purpose.
Auto Incorrect, or for short, AI.
Does the 'Å' pop up if you long press 'A'?
Yes, it's one of the options there. But I'm not doing that, I'm just pressing the A key and it automatically gets transformed to Å once I hit space around 50% of the time.
Isn't there a setting to turn auto-correct off?
Yes but autocorrect is on the whole useful, I'm a bit sloppy when I type on glass and it's probably correct a little bit more than it's wrong.
Actually I'm not sure if that's even true anymore. It constantly "corrects" "its" into "it's" (it even did it just now) in situations where "its" is appropriate. It corrected the "on" in "type on glass" earlier to "in". And half of my "A" gets turned into "Å" (it just happened again and I had to go back and fix it). Maybe it has gotten to a point where it's wrong more than it's right.
You can add a correction going the other way and it may fix the problem (it did for me for a similar problem, anyway) in Settings -> General -> Keyboard -> Text Replacement. Try replacing “Å” with “A”, or “A” with “A”, and see if that helps.
I thought cortex-m0 was taking over that slice of the pie.
Not really. Before RISC-V, the low end was held firmly by 8051, and at the high end, it was a fight between Xtensa, ARC, M0, and "others", be that custom ISAs or something like legally distinct MIPS.
Now, both ends have RISC-V seeping into them.
And I suspect it’s accelerating quickly. This whole space is hyper cost-competitive and pennies matter, so being able to design whatever you want without having to talk to lawyers or pay anyone anything is a huge win and matters far more than whether something takes 1 instruction or 2.
I thought so, too. The Cortex M0+ is quite nice. RPi Pico RP2040 (original) https://pip-assets.raspberrypi.com/categories/610-raspberry-... uses them, and with the RPi on-chip math help (clever stuff) it's quite the joy for your toaster or microwave oven project. RV32EC is 'ok' but the weirdly reduced register set to save a few dozen transistors seems like out-of-control hardware guys without any software supervision - the bane of this industry.
Now-a-days, I actively avoid RVxxx Zwhatever because those guys had their chance and seemed to have learned nothing from the IBM 360: SOFTWARE is what ultimately matters, as long as you don't have ridiculously expensive chips, keep the ABI consistent!
And, ARM learned from M0 and quickly came out with the M0+ --- which SHOULD be the 8051 killer (no offense to my friend John Wharton (RIP), 8051 designer https://en.wikipedia.org/wiki/John_Harrison_Wharton): M0+ is a lower-power, more efficient redesign of M0, 2-stage pipeline, Harvard bus, and optional features (MPU, MTB, fast I/O) that M0 lacks. The RPi Pico has all of these optional features except the MTB (Micro Trace Buffer), but does have 4 breakpoints / 2 watchpoints per core, 8 memory regions, single-cycle I/O port access, 30% less power than M0, and 12% less die area, 32x32 single-cycle multiply, Thumb-2: "32‑bit Performance at 8‑bit Cost" https://documentation-service.arm.com/static/60411750ee93794...
Maybe certain Chinese RV32E variants will get uber popular (WCH CH32V003 under a dime in quantity https://wch-ic.com/products/CH32V003.html ). Maybe.
If RISC-V was good enough for AMD to use it in their controller for their GPUs and it became cheaper than ARM, and NVIDIA is using it in many places, it was better to build upon than getting a change in ARM/x86 licensed and approved by Jim Keller, it's good enough.
It turns out that the cost of waiting years for an ISA change is more costly than fixing whatever problems it has.
I think I get it. I've tried microblaze-v for a while now. And just look at their interrupt handler. https://github.com/Xilinx/embeddedsw/blob/master/lib/bsp/sta... . With the FPU enabled at compile time, that's > 128 memory ops per interrupt. That's insane, especially without an NVIC and chaining and all that. My latency was astronomical, and my maximum interrupt frequency was pitiful. Ended up doing the work (sw and hardware options) to get it to operate more like arm-m, but arm-m doesn't need that work to be done. NVIC is always NVIC, and NVIC is good
Yeah, this is a bug. They should only be saving the FP state if it's dirty.
Also this is one of the reasons I think Zfinx is a better option for embedded (i.e., the standard FP instructions operate on x registers instead of f registers): 31 registers is plenty to hold a mixture of integer and floating-point values, and you avoid the worst-case context save penalty.
Not a bug, just not optimized. Because I think there's a csr to read it the fpu is dirty but... That requires csr extension. It would also increase jitter, which in some cases is more important. At best it should be still there as an option, but also optionally improved
Fair enough. It's a performance issue but not a functional correctness issue.
> Because I think there's a csr to read it the fpu is dirty but... That requires csr extension
Yes, and they already unconditionally read that CSR :-)
The "CSR extension" is an almost 100% theoretical concern. It was the spec authors being defensive in case the privileged ISA was so flawed they had to throw it out in future, while keeping the base ISA. I don't see that happening at this point.
The only exception is deeply embedded cores that drop even basic IRQ and exception support. These are always going to exist and I think they're a sufficiently separate class of processor that they don't really factor into the compatibility equation, because such processors usually only run one program in their entire lives.
You know what, you're right. I was thinking of the timer option. I don't think you can turn off the csr functions on that core. But I've gotten into trouble turning off the timer
> That requires csr extension.
Interrupts require the CSR extension. In practice all RISC-V CPUs support Zicsr.
You can bypass AMD's heavy BSP abstractions according to gpt.
Is that what you think that is here?
Don't you have to save registers on any architecture, or not use them in the interrupt handler?
No. That's also partially in the article. But even in ones that do, usually it's a subset. In arm-m, some registers get stacked on interrupt (basically the caller saved ones in the ABI so any regular functio is automatically IRQ compatible). In this implementation, 64 registers do. Very different from I think it's r0-r3, lr, and pc. Some architectures bank them, so as long as you don't nest or call functions you can just use the interrupt bank.
RV actually allows for that. But not dictating that registers get pushed to the stack, flexibility in how you manage them opens up. So for RV, and some other architectures, you have to mark the function an IRQ and the compiler will know how to figure that out.
Another gotcha is that for AXI and other burst interfaces, the hardware being able to say "I'm going to send you X words" is dramatically better for latency than each one being a single transaction. So if your stack is in a location that requires multi-cycle memory access times, this balloons in timing cost.
Sadly this is a very hard topic to condense into a few sentences. Maybe if I wrote an article on it with graphics it would help. Unsure
We are using RISC-V for AI accelerators to great success
https://ai.meta.com/blog/meta-mtia-scale-ai-chips-for-billio...
RISC-V was a great choice due to being so customizable and extensible.
He addresses this use case in the article.
the significance and allure of risc-v, the reason china is investing heavily in it right now, has little to do with the technical details of how it works under the hood, it's the fact that it is an open standard not encumbered by intellectual property law. even if it isn't technically the best general-purpose processor architecture, it sets an important precedent by proving that it is possible to develop an open public architecture that the world can use to build computing devices without being extorted by a multinational corporation charging licensing fees or a geopolitical superpower enacting tariffs and sanctions.
> it's the fact that it is an open standard not encumbered by intellectual property law.
There are actually many of those. But Risc-V has become, through effective marketing, the Schelling point for anybody who wants to avoid the x86 and Arm ecosystems, both for the rent-seeking behaviors you mention, and also, in some instances, for security reasons.
And, as others have mentioned, the ISA doesn't really matter. As long as it's agreed upon, then the CPU vendors can optimize on one side, and the compiler writers on the other side.
Sure, Risc-V has its warts, but you can certainly say the same about all the rest.
The ISA not mattering I think isn't as true when you account cost e.g. in a huge OOO cpu all the fusions and so on are afaict fairly doable but if you are on a cheaper / worse CPU all those extra bytes in the instruction stream do add up.
The RISC-V fusion arguments from back in ~2018 didn't really pan out. A lot of those fusion opportunities are just instructions now. slli + add? Zba (sh*add). slli + srli? Zbb (zext.*). slli + srai? Believe it or not, also Zbb (sext.*).
Look at that pair of RVC instructions you used instead of a single 32-bit opcode. They are:
* Taking up valuable compressed instruction space; each compressed codepoint has an opportunity cost of 64k uncompressed ones.
* Limited in which registers they can use (usually x8..x15).
* Often clobber their input operand instead of giving a free move.
Also consider that the frequency data that drove the RVC compression decisions was driven by the lack of architecturally fused instructions like sh*add, so any arguments you derive from that data are circular. An instruction can be a good uarch fusion target because it's compressed, and a good compression target because you didn't fuse it in the architecture.
I think designing for uarch fusion in your ISA is coming at it from the wrong end. Fusion is something uarch designers do to make up for shortcomings in the ISA.
And all modern high performance Arm and x86 cores do more fusion than RISC-V cores that are currently on the market.
Intel has being fusing `CMP` and `Bcc` since Core 2 and AMD since Zen 1.
This is
- already one instruction in RISC-V
- an *extremely* common pattern, often occurring once every 5 or 6 instructions.
The combined comparison-branch instructions of RISC-V are its only good feature in terms of instruction encoding design.
This allows a significant code size reduction in comparison with ARM Aarch64, but unfortunately for RISC-V this advantage is frequently not enough to compensate its other defects, especially when reliable code is desired, i.e. where overflow detection is necessary.
Despite that from this point of view ARM Aarch64 is weaker, that is not an intrinsic problem. Aarch64 has an unused block of encodings inside the block used for branch instructions. I have verified that in the currently unused block it is possible to encode not only compare-and-branch instructions covering all the conditions that exist in the RISC-V ISA, but also additional conditions that are missing in RISC-V, where their absence is a problem, like testing for overflow.
I do not know why nobody at Arm had thought to make this extension yet, but it would be very easy to eliminate the only advantage that RISC-V has over Aarch64.
> I do not know why nobody at Arm had thought to make this extension yet, but it would be very easy to eliminate the only advantage that RISC-V has over Aarch64.
Nope. Again, the primary advantage that RISC-V has over Aarch64 is that it is the agreed-upon open specification.
Sorry, haven't been following along, but sounds to me that the argument was a valid one seeing how it made the designers add new instructions.
Not sure if there's an impact caused by the late addition as opposed to always having them, but considering this is a fairly core thing what a program does, not sure what degree of fragmentation this causes on the level of compilers and hardware.
x86 effectively killed innovation in the SIMD space by making instruction set support so fragmented, that people had to target the decade-old lowest denominator.
The arguments were against ISA-level fusion, since they can be fused in the uarch. See for example: https://www2.eecs.berkeley.edu/Pubs/TechRpts/2016/Archive/EE...
Performance is subject to debate and quality of implementation and whether such implementations will ever be financed and made ...
But *code size* is a demonstrable fact.
RISC-V has by far the most compact code of any popular 64 bit ISA, and that was true even of RV64GC. The gap has only widened with RVA23.
Just load up your favourite OS (e.g. Ubuntu 26.04) for various ISAs in Docker and compare the `text` size of various binaries, individually or in aggregate.
In 32 bit ARMv7-M / ARMv7-A had a small code size lead over RV32IMAC, but this is reversed in modern RISC-V e.g. if you look at RISC-V Hazard3 vs Arm Cortex-M33 in the RP2350 (Raspberry Pi Pico 2) where you can trivially change one option setting in your project and recompile and test.
The only exception is that the M33 has a single-precision FPU, which neither the Hazard3 nor the Cortex-M0+ in the RP2040 have.
> RISC-V has by far the most compact code of any popular 64 bit ISA,
Forgot to say “RISC”. Cause else: amd64
No, RISC-V code is much more compact than Amd64. This is easily demonstrated on any real application, such as those in your favourite Linux distribution.
That is false.
All the claims of the RISC-V fans that I have seen in the past compared the compressed variant of RISC-V with the uncompressed variants of the other ISAs.
Most other ISAs, like ARM, POWER and MIPS, also have compressed variants and if RISC-V were compared with those, it would lose.
Moreover, if you use safe compilation options with RISC-V, the code size explodes in comparison with any other ISA, because I am not aware of any other ISA introduced after 1974 that lacks hardware overflow detection, which multiplies by 3 or more the number of arithmetic instructions required for any computation.
This is a new claim that I see now, that RISC-V can be more compact than Cortex-M33 (i.e. where both use a compressed encoding), which I find unbelievable, because if I assembly by hand almost any function that is not too simple I can make it shorter on Cortex-M33 than on RISC-V and I doubt that the current compilers are so bad that they generate much worse code.
RISC-V is shorter on any code that has a lot of branches and negligible computations, but for anything more complex, with many computations and complex data structures, it loses.
I want to try looking at codesize for -Os builds with the different ISAs including the compressed variants you mentioned. As well as dynamic icount with overflow checking.
Do you have any specific project in mind that I could use for testing?
I keep seeing comments here saying that a)compressed instruction are awful for pipeline decode, so they aren't used in any ISA on fast speed and b)risc-v loses in code size if you compare against compressed instructions
I don't understand how the two viewpoints fit together
> I don't understand how the two viewpoints fit together
Well, they don't and they do. Linux runs on everything from an $8 generic IP camera to the world's fastest supercomputers.
RISC-V is attempting to achieve the same feat in hardware, so there will be many implementations at many price points.
As with any of the T-shirts that list 3 things and say "Pick two" it's always difficult to reduce cost, increase speed, and decrease code size.
But...
You can pick two.
So if you don't mind spending the money for things like fancy micro-op caches, you don't care about the compressed decode, and you can still make it run like a bat out of hell with compressed instructions.
Or if you don't mind lower performance, you don't worry about fusing operations, and the pipeline implications aren't so bad, so you can still make something cheap that works with compressed instructions.
It's only when you're trying to pick all 3 (compressed instructions, high instruction throughput, and low cost) that the difficulty of decompressing the instructions becomes problematic.
Or look at it this way. x86 decode is infinitely more complicated than RISC-V decode, and still occupies maybe 2% of the die area.
I specified "popular 64 bit ISA", which comes down to amd64 and arm64. But you can include Elbrus and LoongArch if you want. Or POWER. Or Itanium.
> I assembly by hand almost any function that is not too simple I can make it shorter on Cortex-M33 than on RISC-V
Not if you use the RISC-V ISA properly.
x86 is basically one big cabinet of horrors, but people seem to put up with it because it's "the standard." Then why not with RISC-V? Which is much if not infinitely better.
The article explains why it's worse
The article explains why the author believes it's worse.
> […] then the CPU vendors can optimize on one side […]
I find the statement ironic and somewhat amusing (or bemusing – depending on the perspective) for reasons entirely unrelated to CPU's and/or RISC-V.
I keep hearing the phrase «we shall leave that to the vendors» every now and then. Only a few days ago, whilst attending a working-group session on an emerging data exchange standard, precisely the very much same argument was bluntly stated: «We do not particularly care how complex the specification becomes because the vendors will implement it. We shall leave it to them».
The issue is that «the vendors» are not a single mythical intelligence or force possessed of infinite technical wisdom, unlimited, cosmic scale engineering resources and an relentless desire to right the wrongs.
They are businesses. They have narrow commercial objectives, conflicting priorities, disparities in the engineering talent and resourcing and, quite properly, incentives to advance their own products – you are right, to compete with other vendors. Where an opportunity appears to increase market share, lock customers in, differentiate their platforms and products or shift implementation burden elsewhere, one should expect them to notice it. It is not an accusation, it is merely an acknowledgement that vendors tend to behave like vendors.
So with «the vendors will do X», at best, we may hope that vendors will deliver an interpretation of the specification – to a degree, provided that doing so aligns sufficiently well with their commercial interests. An equally plausible outcome is that they will not – or that they will each implement mutually incompatible interpretations whilst proclaiming full compliance.
> I find the statement ironic,
What you find may or may not match reality. In this instance, I don't believe it does.
> We do not particularly care how complex the specification becomes because the vendors will implement it. We shall leave it to them.
This, of course, is a silly argument. Yet, it is completely orthogonal to the one I was making, and is 180 degrees away from the complaints leveled at Risc-V which are that it is an overly simplistic, nay childish, specification, written in crayon by kindergartners.
> The issue is that «the vendors» are not a single mythical intelligence or force possessed of infinite technical wisdom, unlimited, cosmic scale engineering resources and an relentless desire to right the wrongs.
I find this statement accurate, yet condescending. Who the fuck thinks that they are? Claiming that this is an "issue" with my statement appears to be a reductive argument that I have not thought it through. To be blunt, this statement reveals a hell of a lot more about your ignorance on this issue than mine.
> It is not an accusation, it is merely an acknowledgement that vendors tend to behave like vendors.
And yet, we have seen this play out in x86, with Intel v. AMD, and it worked exceptionally well.
> An equally plausible outcome is that they will not – or that they will each implement mutually incompatible interpretations whilst proclaiming full compliance.
Of course, AMD and Intel were always trying to one-up each other, but that is tempered by the necessity for their improvements to be supported by compilers. By the time an improvement is well-supported, the other side has caught up.
With Risc-V this is even more likely to be the case, because proprietary extensions will simply not be that well supported by major compiler vendors, who have a hard enough time keeping up with the ratified ones.
Isn't almost everything in MIPS long outside patent protection?
even when foundational patents expire, licensing agreements and copyright and trademark and other things remain legally enforceable. chinese companies actually did start investing in mips at one point but ended up getting sued. people tried to open source mips years ago but gave up and just switched to risc-v because it's too much of a legal hassle to try to open source something that was proprietary for decades and has all the legacy baggage of multiple previous owners who want to sue you for any reason they can think of. it was easier to just design a new architecture that was open from the start.
I think the issue is then, if you have the same base lineage and you start extending and fixing things, then it will be easy to overlap with new patents that whomever still holds MIPS IP.
RISC-V is mainly a way to avoid IP conflicts, not as a technical breakthrough. MIPS itself was a boring (this is good) implementation of the original RISC papers, but they asserted a bunch of things legally which eventually, along with the legal work of Arm meant that ISAs were effectively owned by their parent corporations.
I'd assert that much like 3rd parties being able to make replacement car parts, that we should be able to make ISA compatible chips. But here we are, RISC-V needs to exist and does, but for legal reasons, not technical ones.
*edit, I forgot to refresh before posting, what bjornnn said.
It's not just China that has an interest. Multinational corporations also hate being charged licensing fees (see Qualcomm vs. ARM). Here's a list of RISC-V members: https://riscv.org/members/
lol the government of brazil is in there
Why is that funny?
it’s funny because it’s unexpected. one of those members is not like the others. the rest are tech companies.
it does make me wonder what prompted them to join. it would suggest to me there are forward looking people in Brazil’s government. I am impressed.
I consistently see a level of competence and professionalism in South America that has left the building in the states.
I wrote an RV64IMA emulator recently. I just needed a virtual CPU core that could boot linux, and RV64IMA seemed like the simplest way to do that - and I think that's more or less true.
But then I wanted to be compatible with off-the-shelf toolchains and binaries, and I found myself needing to extend the ISA profile to RV64GC. Not a huge lift, but it involved pulling in a softfloat library. That got me as far as booting Alpine linux.
And then I wanted to be able to boot Ubuntu, which needed RVA23, which was comparatively a much bigger lift, involving the vector instruction set among many other things. At this point I think I'd have been better off just emulating aarch64.
Ubuntu 24.04 LTS exists and needs only RV64GC and will be supported and enhanced for many more years.
Debian has no plans to require more than RV64GC.
RVA23 is a very good thing in certain markets, but nothing forces you to support it for a personal project.
I cant see debian remaining on rv64gc later on when enough rva23 boards are purchasable
Why? It'll still run fine.
Just like Debian still runs on original x86-64-v1 from 1999, not x86-64-v3 (needs AVX2,FMA, BMI1, BMI2, LZCNT) or even x86-64-v3 (needs AVX-512).
Similarly, Debian for arm64 still requires only ARMv8.0-A from 2011 not even ARMv8.2-A (everything from A75/A55 to A78/N1/V1) let alone ARMv9-A (A710, A510, X2 and on).
Why would they do in the RISC-V world what they totally haven't done in amd64 or arm64?
No, debian requires ARMv8.0-A + FP + NEON, as those are optinal extensions (even optional in ARMv9.0-A)
SVE2 is compulsory in ARMv9-A, but NEON is optional?
https://support.arm.com/documentation/109697/2026_06/Feature...
> In an Armv9.0 implementation, if FEAT_FP and FEAT_AdvSIMD are implemented, the following features are implemented: ...
This implies they don't have to be implemented.
https://support.arm.com/documentation/109697/2026_06/Feature...
> FEAT_FP is OPTIONAL from Armv8.0.
> FEAT_AdvSIMD is OPTIONAL from Armv8.0.
But also:
> All Armv8-A systems that support standard operating systems with rich application environments also provide hardware support for Advanced SIMD instructions.
and
> All Armv8-A systems that support standard operating systems with rich application environments provide hardware support for Advanced SIMD and floating-point instructions. All Armv9-A systems that support standard operating systems with rich application environments also provide hardware support for SVE2 instructions. It is a requirement of the ARM Procedure Call Standard for AArch64, see Procedure Call Standard for the Arm 64-bit Architecture
So, both FEAT_FP and FEAT_AdvSIMD are optional for Armv9-A and Armv8-A.
But both are mandated in cores for "rich operating systems", which basically means it's mandated by the OS.
Also, Armv9-A on OS level mandates SVE2.
Near the end of the essay, the author mentions that the folks at Berkeley considered OpenRISC.
Would that have been a better path do go down, to throw a bunch of work, money, and R&D after, or is there anything inherently bad about that design besides delay slots?
I kinda feel that even the smartest people will build great things on crumbling foundations as long as those foundations are available. I'm thinking of NASA embracing RISC-V or anyone who decided to write secure-by-design software in C.
*edit - rephrased question for clarity
It's basically MIPS all over again
The conclusion is honest, and you can of course brute force any ISA into any role. I used to loathe x86 for that reason, but now that I'm older I respect the game.
I think MIPS is a great example, and even there I don't think there's the bizarre bifurcation of ISA options RISC-V brings to the table.
As a fellow olderster, I can't help but think that after almost 50 years of "ISA X is sooooo much better than x86 it's obvious ISA X is the future and x86 will be dead Real Soon Now (for whatever todays version of x86 is)" I can only shake my head ruefully and say "ping me when that happens".
Controversial Take (that history proves isn't): Software matters; ISAs don't.
x86 chips don't truly exist anymore. They only use it as a compressed ISA for a more capable internal representation that can be freely updated at any time.
I keep seeing this line of reasoning and have no idea why it's relevant. You don't program that 'internal representation'. The software people want to run only care if that software doesn't run. Cyrix, Transmeta,NexGen, Centaur, WinChip, etc., etc, theoretically had "more capable internal representation". The only thing that actually matters is "does it run the exact same x86 software I bought X many years ago" and "does it run it at a decent price/performance ratio". Everything else is dick measuring.
Today, we have Intel and AMD, and some bit-player embedded folks.
Sort of.
They always had a much cleaner instruction set internally, going back to the 8086.
This is a load of bullshit that largely exists as copium to explain how x86 did the impossible and made a superscalar CISC processor. x86 is doing the same thing that (to my knowledge) all high-end processors do, yet no one tries to call out those chips as compiling to a different internal ISA. But you also don't see any chips trying to run with multiple ISA modes: the closest you get is 32-bit and 64-bit modes coexisting, or ARM's Thumb instruction set.
Amen. I remember the about 6 months when the benchmark cawboys were screaming that they had to be able to have access to directly program the Pentium Pro micro-instructions because 'that would be so much faster' and no matter how much the Intel architects who actually knew how things worked said "I don't think those words mean what you think they mean" there was some conspiracy to keep the PPro from achieving it's max performance...as if Intel didn't want the PPro to show it's max performance.
Humans are weird.
I haven't kept up with POWER after POWER9, but I recall it to be a true hardwired control RISC, pure as the driven snow. This had some interesting properties (along with other clever designs like eFuses and pNOR) for creating a really credible security posture. They do have a millicode system and chicken bits for oops moments (which are kind of an opposite risk, if you don't get those right for unexpected problems).
A lot of the implementations have used cracking and grouping. They were/are definitely not doing anything like a 1-to-1 mapping between externally visible instructions and their implementation.
Whenever I see someone say this I'm thinking the following:
If what they say is true, then x86 won because ISA doesn't matter, precisely because ISA is the public instruction set architecture. If you can convert anything to a better representation then the argument of exposing the better representation doesn't actually follow.
Additionally, you are claiming that an internal implementation detail that only Intel and AMD know about is secretly implementing your favourite instruction set, which when you think about it, is incredibly implausible and impossible to prove. It's eerily similar to an unfalsifiable theological claim.
Then there is the silly argument that x86 chips don't exist anymore, when x86 chips have distinctive differentiating factors that make them unlike chips that implement other ISAs. The most obvious one is that x86 is primarily used in the personal computing and server space. This means the chips focus on high single threaded performance with large caches and large core counts plus swappable memory and storage devices, whereas most ARM and RISC-V devices target a completely different space, primarily embedded devices where everything is included on the PCB and there are very few external interfaces. You have to be pretty delusional that an unfalsifiable claim on an internal architectural detail of a CPU core somehow invalidates the rest of the silicon that happens to be on the same die.
I hate comments like yours because they are self defeating and require a lot of effort to debunk.
There's still repercussions to the unaligned variable length instruction set that is x86 though, and the decoder and prefetch have to deal with the insanity that falls out from it... ultimately limiting how parallel the instruction decode and dispatch can be.
X86 is the best argument that you can build a fast efficient RISC-V chip... because the X86 instruction set is a much bigger mess.
It just blows my mind sometimes when designers don't learn insanely obvious lessons from the past, basic stuff like "complexity is evil" and "make the fast path overlap with the most common use cases" and "a standard with N optional extensions is actually N! (N factorial) standards."
That being said all real world architectures seem to have messy corners and warts. RISC-V was a chance to do away with a lot of that and they... didn't?
> X86 is the best argument that you can build a fast efficient RISC-V chip... because the X86 instruction set is a much bigger mess.
I don't think that's actually true. There's weird historical baggage and whatnot. But if you're running in long mode, it's actually a fairly sensible architecture with useful memory addressing modes.
> because the X86 instruction set is a much bigger mess.
One of the things I've been playing with off and on in my spare time is poking at the x86 ISA. And yet, while the ISA does have some weirdness to it, it is a lot less weird than its reputation makes it out to be. For example, the sum total of the opcode form amounts to does-it-have-ModR/M + size of immediate operand (in bytes)... which honestly strikes me as simpler than RISC-V instruction form decoding.
I know there's an earlier criticism of RISC-V that points out that one of the common instruction sequences for which "macro-op fusion" is the suggested solution involves 5 instructions... and I don't think any of the existing chips ever fuse more than 3 instructions?
You've also got tons of prefixes with opcode dependent rules on what's allowed there, the opcode field itself is variable length (I've seen up to four bytes), you've got instructions that treat that immediate field as additional opcode bytes, etc.
The opcode is 5 maps (8, actually, but only 5 are occupied) of 10-bit opcodes, with the presence or absence of 66/F2/F3 prefixes providing 2 of those bits. If you ignore how the manual describes prefixes and look at it like that (which is suggested by the VEX encoding process), the decoding process becomes a lot simpler. In fact, with one singular exception, this is sufficient information to index into a map to figure out how long the immediate field is and whether or not ModR/M is present.
2^N I think, but who's counting.
There is a general pattern I've noticed, where people from past generations fail to share the lessons they have learned somewhere that is accessible for the next generations, so they are stuck repeating the lesson.
In particular, the next generation might recognize some aspects that seem bad and be confused over how to prioritize correctly because they don't know any better.
But they do share it.
It is just that it is some combination of behind closed doors, for competitive advantage, and/or the new generations don’t want to hear it.
Previous generations had learned long ago that sharing everything in public, or even in patents, was a bad idea for long term survival, a lesson that has now taken on a more extreme form.
They even loudly declared how they were going to clean up all the messy corners and warts.
The underlying truth seems to be that a “clean” ISA doesn’t by nature make the beer taste better, and many of the warts probably have a reason for existing.
My disagreement with the article is mostly the following:
RISC-V is not an ISA, but an ISA generation framework.
If RISC-V would've standardized aarch64 1-to-1, the end result would've still been a huge extension mess, because a lot of people (RVI member) have different requirements and a very happy to build their own subsets, which would then be upstreamed because multiple vendors want the same subsets and compatibility between them. Obviously it would've been better, similar to if RISC-V spawned with RVA23 done, but development takes time and RISC-V International started, because people where already using RISC-V.
RISC-V also is the most DOSed ISA, with people proposing crazy stuff. Just the other day somebody proposed an instruction that would do up to 2^30 16-bit comparisons in one instruction at the largest VLEN. Because they wanted to improve their string processing usecase.
---
In my experience RVA23 matches aarch64 and x86 in uop count (without fusion), code density is better, instruction count is slightly higher. The biggest impact on the instruction count advantage of aarch64 over RVA23 is a single instruction, load-pair, which gets cracked at decode in every high-performance implementation, because it writes to to registers.
The Arm approach to code density is using multiple writeback instructions that have to be cracked and the RISC-V one is RVC. Both prohibit simple linear scaling of parallel decoding, so code density seems to have mattered to Arm enough to make the tradeoff worth it.
It’s kind of funny that all of the complaints about optionality apply equally to Vulkan. Google even created the same profile solution with “Android Vulkan Profiles (AVP)”.
I suspect Vulkan suffers from the same design by committee problem, which similarly caused it to miss seemingly basic features in the base spec that then need to be filled in with extensions and also made it too difficult for developers to want to move too.
Well, graphics programmers were used to the mess from OpenGL days. Now compiler writer and hardware designers get to share the sorrow.
Wayland too!
Why is he complaining about everything being optional in RISC-V? Isn't that the whole idea of RISC-V? The market can sort it out for themselves. RISC-V is already dominant in the MCU space despite its flaws, and many of them will be solved in due time.
Most MCUs are used for dead-simple solutions, like electric blankets and microwaves with segment displays or LEDs. Whether their interrupts are handled in 44 or 22 cycles doesn't really matter that much.
And RISC-V does have a link register, making returning much faster when the parameters for the interrupt can all fit in registers and no external memory access is needed, as is the case with most MCUs which put the stack in RAM. To fetch the return address an external memory access is always needed even if there are no parameters.
He explains, at length: there is no sane way to determine what the hardware you are running on actually supports, and so there is no sane way to ship compiled code that is both compatible and performant.
We already had the mystery meat CPU wars several decades ago. We know how to make sane ISAs now and should be past that.
You don't need to probe what hardware you're running on because you know being the manufacturer. The code is bespoke for your solution and nothing more. No foreign code is going to run on it.
Different problems require different solutions. An electric blanket doesn't need a barrel shifter for multiplication or even floating point hardware. The ISA can change depending on what's needed to solve a particular problem, not to provide an "one size fits all" solution.
I don't think I've read a more "doesn't actually know anything about how software is produced, but with absolute confidence knows everything about it" post in a very long time.
So you write software for a platform you know nothing about?
Very often. Yes. Or software that will run on any similar arch by auto detecting the environment.
> So you write software for a platform you know nothing about?
That's how a sizeable chunk of software is written and shipped.
Runtime detection of CPU features is very much a thing, and is in fact used extensively in software you use or interact with every single day.
Just as a quick example, OpenSSL's approach for x86_64 is OPENSSL_ia32cap
https://docs.openssl.org/master/man3/OPENSSL_ia32cap/
This ensures (in theory, at least) that even if you're using your linux distribution's openssl library which is more generically targeted, you will get optimal/native runtime performance for your actual CPU.
If you knew anything about ASIPs you would know that you're complaining about yourself.
> You don't need to probe what hardware you're running on because you know being the manufacturer. The code is bespoke for your solution and nothing more. No foreign code is going to run on it.
In practice, this is not the case. The scenarios mentioned in the article involving binary blobs are pretty common, as well as other similar scenarios.
Really, I'm going to go out and say it bluntly: it is just completely freaking stupid to make an architecture where everything is optional but you have no way to query what's present. If you're going to go the optional-pieces route, you have to have a query mechanism of some sort. As the article explains, you cannot even trap instructions on RISC-V to figure out what your core supports, because bad instructions might belong to some other option. Complete. Idiocy.
I'm not an embedded programmer myself, but from what I've heard... it's actually a pretty big assumption that the software people know what model hardware they're running on.
Especially consider the possibility that a product manager decides to swap out the core for a different core to save 5¢ on the BOM. Does the product manager know to ask if the two cores follow the same RISC-V profile? Do the software programmers think to ask? How about communicating the change to all of the vendors or contractors providing you binary blobs? I don't know how likely it would be for a scenario like he author here describes, but it is definitely a plausible scenario.
If the product manager isn't an engineer he shouldn't be making these kinds of decisions.
That doesn't really happen in the embedded space.
Even if the core was supported just fine, all of the IO mux stuff is pretty much guaranteed to be different even with the same chip in a different package.
You're looking at explicit support for each chip.
I worked on a project porting from an STM32L073 to a STM32U073, which management were assured was a complete drop in replacement. Well, it was only in the sense that you could drop one onto the old PCB. It became a running joke how many software compatibilities we ran into. My favourite was an "LCD clock disable" bit became "LCD clock enable". And this was for a specifically chip designed to be an easy replacement.
I'm not sure this is a real problem - for embedded you know a priori - for arbitrary desktop/SBC machines, misa will be available in kernel mode and /proc/cpuinfo will be available in user mode.
Well, misa won't be in most cases since you'll be running ins mode rather than m mode for most kernels on an application core (and misa won't tell you about the X* and Z* extensions).
But you'll practically be passed a device tree from SBI that will tell you.
He actually explains this too. You only know at compile time what you're building for. For example with microblaze-V, I often tweak what ISA I'm generating. If I ran the same elf without thinking about it, who knows what could happen given the instruction collision problem
There is a very easy way to determine what hardware you are running on, it's the baseline of the OS.
Armv9-a doesn't mandate FP or SIMD support, but nobody does detection for those, why? Because it's required on the OS level. Similarly OS are moving their baseline to RVA23 so software can assume all of those instructions are available.
> The market can sort it out for themselves
Because nobody will write software for 300 unique hardware variations of a platform that have inconsistent capabilities. Consistency is one of the reasons why x86-64 with extensions like like SSE, AVX2 etc is popular.
Noone uses an 8051 because it's elegant. Billions are still still sold every year because no matter if you learned it in the 70s or last week and no matter who made it, the basics are exactly alike. Software matters; ISAs don't.
>You learned it in the 70s [emphasis mine]
I really don't know anything about this space, but you just said that 8051 is dominant because it has one dominant architecture since the 70s. It has hundreds of manufacturers making identical parts.
As you say, software matters. If the Software can't run because of hundreds of extensions that can't be checked for, then you're going to pick a target that works, no? So in fact the ISA matters most: which ISA has the most software? Which ISA means my software runs on the most devices?
I really don't know anything about this space
And yet you couldn't help yourself...
but you just said that 8051 is dominant
I said absolutely no such thing.
If the Software can't run because of hundreds of extensions
The software in the x86 world runs because there aren't hundreds of mutually incompatible extensions. I think the last time there was a major completely incompatible x86 ISA divergence was AMD "3DNow" vs other SIMD extensions. AFAIK the rest were "processor X got feature Y later than competitor Z".
Which ISA means my software runs on the most devices?
Easiest question evah: x86.
Yeah, I completely misinterpreted you post. Apologies.
Every time I've seen someone use an 8051 in the past twenty years, it's had new, bespoke software written for it. They were more used because they were a known quantity with the patents obviously dead rather than support for existing codebases.
Interesting comment. I suspect without solid facts that new bespoke stuff is mostly either 1) some ARM variant, or 2) some rando US$0.001 Chinese uproc. I think 8051 survives because there's many decades of experience using it, but as I understand the cool kids going into embedded don't think the boomers 8051 is fun and the pool of talent is shrinking fast. SO we'll see what the future holds.
Those aren't mutually exclusive. Some of the sophgo and bouffalo chips have 8051s for always on cores, and riscv for the main cores.
They didn't choose 8051 there for experience, but because it was a tiny core with a decent IPC they could license for a small part, then focus on the main cores. I wouldn't be surprised if they eventually switch to riscv there too.
Also, these 8051 cores tend to be extremely diverse. I don't think I've come across cores from different manufacturers that were actually compatible for real code. They all seem to want to handle accessing 16/32 bit memory differently, have different interrupt details, etc.
Interesting...I don't know much about sophgo and bouffalo chips. Not surprising since the 8051 is patent-free these days. Something I found crazy is how many places someone embedded an 8051 core. Like the tire pressure monitor in every tire these days. Fun stuff.
> Because nobody will write software for 300 unique hardware variations
Who said they have to? One can select a RISC-V configuration for a baseline for a particular purpose. Desktop? Choose the one that's most powerful.
ARM is more popular than x86 and is less consistent than it.
I believe the market will standardize on certain extensions for specific solutions. No one is going to make a mobile phone with only RV32I, for example.
Yeah, that's the point of the profiles. A curated set of extensions for common use cases like application cores for generic software to target.
How can you use consistency and SSE/AVX in the same sentence?
SSE has inconsistencies like SSE4.x vs SSE4a. AVX is an even more mixed bag. There are some 19 AVX-512 extensions and ZERO chips support all of them.
The situation is so bad that AMD and Intel got together to make AVX10 to unify everything. That seemed great, but Intel now has AVX 10.1 and 10.2 in addition to the base set, so there we go again...
x86 is a massive battleground with tons of competing extensions like FMA3 vs FMA4 (why did FMA3 win???) and in cases where one of the competing variants didn't win, we get something like virtualization extensions being completely different between Intel and AMD. There's also the rash of security extensions that have gone through various support and dropped support (not to mention using some of this stuff for market segmentation and further fragmenting the ecosystem).
x86 is anything but consistent if you look into its history (or even it's present).
> but Intel now has AVX 10.1 and 10.2 in addition to the base set
Intel committed to not slicing and dicing the AVX instruction set going forward. AVX 10.(n+1) will not remove instructions that were in AVX 10.n. Feature testing is also easier: a single feature bit and a single version number.
I bet Intel's management will find some new counterproductive way of segmenting the market but AVX-10 (and therefore AVX-512) should be safe now.
>"RISC-V is already dominant in the MCU space[...]"
Where are you getting the idea that RISC-V is dominant? As someone who works in this space, that doesn't jive with my experience or the sources I've seen.[1] 32-bit microcontrollers only recently achieved a majority market share for gosh sakes!
RISC-V is claiming that they have achieved 25% market share across selected segments, but they're still behind ARM (and x86).[2]
[1] https://www.grandviewresearch.com/industry-analysis/microcon...
[2] https://www.aestechno.com/en/risc-v-2026-arm-x86-market/
Risc-v is nowhere near dominant, people are just being swayed by headlines such as Western Digital or Nvidia shipping billions of risc-v cores.
I do find it odd that you go on and compare to x86 marketshare however, the topic you've quoted is very clearly about MCU and whilst 8086 MCU still exists they haven't been used in greenfield projects for decades. Let alone any more recent x86 implementation.
Because it's in stuff where you don't see it: in your vacuum cleaner, your toaster oven, your microwave or your electric kettle.
Do you really think Chinese manufacturers are going to buy ARM MCUs when their budget for a controller is less than 10 cents?
ARM has long ceded this market to RISC-V. It's mostly focusing on high-end application MCUs and AI now.
And lots of newer stuff is making use of standardized boards like Raspberry Pi Pico (RISC-V and ARM hybrid) or ESP32 (RISC-V too on some versions).
It's used widely in Chinese stuff (which is basically everything) so in terms of volume it's probably already dominant.
In terms of dollar volume ARM is still the leader, especially for higher-end (application level MCUs) stuff. RISC-V MCUs with MMUs or MPUs are scarce at the moment.
> RISC-V MCUs with MMUs or MPUs
MPUs are more common. The Physical Memory Protection option is basic and allows ranges of memory to be set unavailable in user mode. A few well-defined ranges do let you lock a user process down securely but it's not a real MMU. Low-end microcontrollers don't have enough RAM to warrant a real MMU.
The RISC-V core in the Raspberry Pi RP2350 has PMP as do the ESP32 cores.
Yet it's royalty-free and good enough for Espressif (maker of ESP32) to move exclusively to the RISC V open-source instruction set architecture [1].
"Good enough ISA plus zero licensing cost" beats "perfect ISA plus royalties" in the embedded space.
Also, let's not forget that the reason the world is built on the von Neumann architecture is that it was made available for free.
[1] - https://www.eenewseurope.com/en/espressif-moves-exclusively-...
Why didn't they make their own ISA long ago? Then they could have zero royalties. AFAIK ESP8266 was already its own architecture.
ESP8266 uses an Xtensa CPU like the ESP32 (just a non-customizable preset)
yeah thats kind of the conclusion if you read the article entirely...
Started reading, however I wanted to add this in: a lot of people expect RISC-V to do too many things, and nearly all of those things are "beat every other architecture out there in every way/shape/form, while also being open".
The reality? The fastest "available" RISC-V CPUs don't match the best chips in terms of speed, power consumption, or die area. "available" obviously means the chips that have been released to the public and can be independently benchmarked.
I do think that is okay, however I also think that those involved with RISC-V aren't helping much, and current attempts at standardizing seem to be just creating a bigger problem.
That being said, RISC-V does seem to perform well in specific niches.
Random minor-ish notes:
- A big problem with extension detection RISC-V has is that there's no central authority mandating vendors to not overlap things (obviously, given RISC-V being an open standard), so basic bitmasks for supported extensions is generally rather problematic (and of course even if you collected a standardized bitmask of all extensions from all vendors, it'd grow quite massive quite quickly); you'd at least want some grouping/marking by vendor, if not full extension strings. That said, it would be nice to at the very least have some standard in-memory blob format if nothing else, that you could query from any OS/libc. (which maybe somewhat-exists to some extent with a C API meant for libc, but as-is still doesn't attempt to figure out vendor extensions).
- many, if not the vast majority, of aarch64 TBZ/TBNZ are probably branching on a boolean; something RISC-V can also of course do in one instruction. Generally, comparing instruction frequencies across ISAs is messy if not approximately meaningless due to different sorts of things existing for solving the same tasks.
- "Having this happen means that instead of a clearly-understandable crash you get ... well ... anything." - RISC-V will do you one better - it doesn't even guarantee a crash when an instruction isn't defined at all! Overlapping extensions is definitely messy for disassembly, sure, but that's also just basically unavoidable as long as RISC-V is open (see my first point). (perhaps there could've been stricter rules for reserved-for-standard encodings than reserved-for-vendor ones? of course still doesn't help vendor encodings, nor non-compliant vendors)
Some more:
> The spec says that bit must be zero, and yet no encoding uses the space opened up by that bit being one.
The spec says "the code points with shamt[5]=1 are designated for custom extensions.", so the space is specifically reserved for custom vendor extensions.
So, if I wanted to add a custom "dzaima.c.clear_top_n_bits rd, imm5" instruction, that's space I could safely put it in, knowing that no future standard instruction will be added there that I may regret overlapping. So while that space goes unused in the standard, its existence helps with the overlapping encoding problem!
> For I-type instructions, bit 1 [...], bit 11
Of course, that's cherry-picking two of the 25% of bits that have multiple positions they come from, and specifically 11 as it's the worst one. Full stats:
So that's like 9 muxes for merging all immediates to the same place (or less of course if the different encodings' immediates go to different places), the rest is just wires.
Obligatory note is that some of the funkiness is to place the sign-extended bit in the same bit position, so some saved muxes from that.
Now, I am a "software person who's never written verilog", but I highly doubt a 3:1 mux is as cheap as a 2:1 mux in silicon, so even if you always need to merge in the sign bit, reducing the number of cases is still beneficial.
Compressed does make it a ton more ugly though (combining both 32-bit and 16-bit instruction encodings, placing the 16-bit ones in the low 16 bits):
looking at aarch64 on https://asmjit.com/asmgrid/:
Fun! (lsl being a subset of the bitfield extract instrs is neat; tbz's similar-functionality 6-bit field is just entirely-differently placed though. Also.. using the Rd slot for an input-only Rt? that's one thing RISC-V doesn't do, even across compressed and 32-bit instrs!)
> many, if not the vast majority, of aarch64 TBZ/TBNZ are probably branching on a boolean
None are. There is CBZ/CBNZ for that. https://www.scs.stanford.edu/~zyedidia/arm64/cbnz.html
It is just THAT useful to branch in a bit.
Both clang and gcc do actually generate TBZ/TBNZ for checking a bool: https://godbolt.org/z/K6evhaxGT
Some stats on an aarch64 binary of my current main project (1.6MB .text, 6600 symbols as per whatever "nm the-binary | wc -l" includes, from "objdump -d the-binary"):
Said project doesn't do fixed bitfields much (there are some, but a chunk of those test multiple bits) so unsurprisingly not much. (I could imagine that the kernel has significantly more, but it's an edge-case (though perhaps an important one) of being basically massive amounts of fixed configurable glue)
Did a quick grep over object files of a half build defconfig kernel:
That is quite a good bit more evenly-spread (the "..." is 5159 instrs).
Wonder what's up with bit 21; if whatever uses it so much is repositionable (and not an aarch64-specific thing), could save like 2KB on x86-64 via putting it in the low 8 bits instead.
Just noting, even if instructions were 100000000000000 bits long, reserving a single bit for 16-bit encoding would waste 50% of the instruction space.
It's not wasted when it makes programs overall smaller, as it does.
It is wasted if its reduction is less than that of alternative uses for that instruction space.
Such as?
There is still plenty of unused 32 bit (30 bit) opcode space.
> Say you want to store a byte to a register plus offset. What range of offsets can a [compressed] 16-bit instruction encode? Zero through three.
If a compressed instruction could load or store a word to a word-scaled offset 0-3, relative to a register base address, that would be quite useful. It could be used for accesses to all structures four words or smaller.
In thumb, it can encode 0..31
Honestly, I would feel uncomfortable if I were designing an instruction encoding and came up with some addressing mode format where there are two bits for a displacement. I would pull myself aside and have a word with myself. That's just me, though.
And Arm dropped a T16-like encoding entirely from their 64 bit instruction set.
If they did everything exactly the same they would be the same ISA not different ISAs.
It's just as easy to point to things that RVC can do that T16 can't.
You need to look at a far larger picture to decide on who made the better decisions overall.
I can definitely see his argument, although I still do believe RISC-V did a lot of things better than x86...
I really do hope that the arch is eventually able to fix this. Better that there be an open ISA than them all be closed IMO.
Better than x86 is a low bar when ARMv8 exists.
And personally, I'm not even sure it crosses that bar.
RISC-V somehow manages to be more fragmented than x86 (which is impressive), and just can't compete on instruction density.
I think a large part of the issue with RISC-V is that it predates (public knowledge of) ARMv8 by a year or two, so it couldn't use it as inspiration. If you compare RISC-V to 32-bit ARM, the comparisons are much more favourable.
Everything I've seen is that rv64gc is very competitive with aarch64 wrt code density.
The article makes the case that RISC-V achieved code density the wrong way. Instead of compressed instructions, ARM has fixed-size instructions with richer semantics.
The fact that it's only "competitive" with aarch64's code density is a solid black mark against RISC-V.
The only reason it's "competitive" is the compressed instructions, which means it's paying all the costs of variable length instructions, yet only getting marginal benefits. IMO a modern ISA taking advantage of variable length instructions should be able to absolutely smash the code density of a fixed width ISA like aarch64. At minimum, it should be competitive with x86 code density, if not smashing that too (because x86 has a lot of legacy baggage)
Compressed instructions aren't a bad idea for very small cores. They give you a decent code density boost with minimal added complexity.
But for large cores you either want to go full fixed length (like AArch64 and Qualcomm's proposal, which bought non-compressed RISC-V into the range of AArch64) or adopt a much more complex variable length scheme that can actually beat x86 on code density.
There's a huge difference between 2/4 byte variable density and 1-15 byte variable density. And as I've said in other places, my experiments showed that it ended up being kind of across the board less than half a pipeline stage to handle C instructions, kind of orthogonally to decode width.
It is a different front end design, so that's why Qualcomm didn't want to reengineer their aarch64 core more than they had to, but the rest of the riscv community was right to not embrace it.
Not to mention that a lot of the aarch64 derived pieces in the proposed qualcomm extension are almost certainly patent encumbered. Qualcomm can absolutely handle just about any patent fight, but other risc-v companies can't.
I agree that 16-bit/32-bit variable length would struggle to beat x86. But I suspect it could have gotten close, simply because x86 wastes a huge amount of its advantage on legacy cruft.
The important point is that there is no reason why a 16-bit/32-bit encoding shouldn't have smashed Aarch64's 32-bit only code density.
My secondary point, is that why should RISC-V limit itself to just 16-bit/32-bit? It has the encoding space set aside for 6 bytes, 8 bytes, 10 bytes and all the way up to 24 bytes (which is overkill). If it's already paying the variable length tax, it should be making better use of it. IMO, a 2, 4, 6, 8, 10... byte scheme should be able to massively improve on x86's code density.
> I agree that 16-bit/32-bit variable length would struggle to beat x86. But I suspect it could have gotten close, simply because x86 wastes a huge amount of its advantage on legacy cruft.
I'm saying the opposite. Maybe some theoretical CISC-V would leave RISC-V behind, but x86(and -64) makes wild choices for instruction density, and RV64GC already clearly beats x86-64 in .text density.
> My secondary point, is that why should RISC-V limit itself to just 16-bit/32-bit? It has the encoding space set aside for 6 bytes, 8 bytes, 10 bytes and all the way up to 24 bytes (which is overkill). If it's already paying the variable length tax, it should be making better use of it. IMO, a 2, 4, 6, 8, 10... byte scheme should be able to massively improve on x86's code density.
There's nonlinear issues as you add more options. A 16-32 decoder is pretty simple, a 16-32-48 isn't the worse thing in the world (and a 32bit immediate might make it worth it), but you start to hit weird explosions in gate count once you go much past that. Hence x86's splitting into essentially multiple front end banks in modern designs, and even then typically only has one decoder per bank that can decode everything, and even that takes multiple cycles for some instruction sequences, even just to discover the length.
The larger lengths in the RISC-V spec are more targeted towards bespoke stuff like GPGPU that's maxing out issuing a single instruction per instruction stream anyway. When you look at shader machine code, it's clear density was essentially an afterthought, but they love them some 64bit wide instructions. Which unsurprisingly is pretty much the same width of vertical microcode in archs that still do such a thing.
> and RV64GC already clearly beats x86-64 in .text density.
Maybe I'm misremembering. Or maybe the numbers I'm remembering took into account the fact that most compilers unroll more aggressively on x86 than on targets they consider to be "embedded" (another pet peeve of mine)
I stand by my assessment that the code density of rv64gc (and especially rv64g) is lower than it would be if they had actually put a focus on code density.
> A 16-32 decoder is pretty simple, a 16-32-48 isn't the worse thing in the world (and a 32bit immediate might make it worth it), but you start to hit weird explosions in gate count once you go much past that.
Not sure I would say 16-32 is simple, certainly massively simpler than x86. My point is that you have already paid the tax for going variable length, and 16-32-48 isn't that much more complex. And probably worth it for 32-bit immediate/offsets.
And maybe 16-32-48-64 is worth it... Hard to tell, but I wouldn't entirely rule it out without study. The advantage would either be immediates/offsets that are too big to fit in 48 bits. Or some kind of VLIW style scheme which actually packed three 20-bit instructions into aligned 64-bit packets. (Or other mixtures of sizes like 30-30, 30-15-15, 40-20, or 15-15-15; We are talking about a complete break from RISC-V. There is a thread somewhere on HN where we brainstorm something like this).
But beyond that, no point really. Just pointing out that RISC-V reserved the space.
Maybe I need to prototype the 64-bit aligned packets idea someday, at least far enough to get instruction density numbers.
> And maybe 16-32-48-64 is worth it..
It is, with a prefix encoding, you can reuse the RVC decode path 1-to-1 and get the 48/64-bit instruction starts with a simple bitshift (or simply handle the 48/64-bit instructions via the fusion path). This seems to be the encoding direction RISC-V is headed in.
> The fact that it's only "competitive" with aarch64's code density is a solid black mark against RISC-V.
Arm uses complex instructions with multiple writeback, that require cracking, to improve code density. RISC-V uses a variable length encoding to improve code density. Both have anaougus decoding complexity, but RISC-V achieves higher code density, while impacting the cost of things before decode (how much, idk).
But imagine the code density you could get combining both strategies.
> Arm uses complex instructions with multiple writeback, that require cracking, to improve code density.
While smaller cores have the option of cracking the multiple writeback instructions, many arm cores just pay the extra cost of having a 3 read, 2 write register file, so they aren’t actually cracking those instructions.
They do crack other instructions.
But the cracking seems to be more about ALU limitations (aarch64 has instructions that can do both a shift of any width and an add, but the ALUs might not support this, or only support smaller shifts of 1-3 bits (useful for addressing)
What this means is that despite the cracking, each μop in an aarch64 core is quite a bit more powerful than a typical RISC-V instruction (especially compressed instructions).
So to be competitive on backend performance, a high performance RISC-V is going to spend a lot of resources post-decode doing massive amounts of instruction fusion to try to get μops of similar capabilities to aarch64 (or just settle for simpler μops, and pay scheduling costs of more μops)
So the costs of the RISC-V compressed instruction approach aren’t just limited to pre-decode.
> While smaller cores have the option of cracking the multiple writeback instructions, many arm cores just pay the extra cost of having a 3 read, 2 write register file, so they aren’t actually cracking those instructions.
No, every high performance core I know of cracks them at decode, some re-fuse some of them after rename (Apple). Because otherwise you would need to rename up to 4 destinations per rename slot, effectively 4xing your already limiting rename stage.
Cracking other stuff later in the pipeline isn't expensive.
Really? Interesting.
Though, I guess fusing after cracking makes things easier because you don't actually have to search for fusion candidates (supported by the fact that Apple's Firestorm doesn't seem to make any effort to fuse things that aren't alu + branch, crypto, or amx)
Edit: removed
Yeah, fusing is probably easier, if you already know what to fuse. On the other hand, if you want to fuse load pair on RISC-V you have the entire rename stage to figure out which uops can be fused independently of the rename stage, if fusion haopens after rename as well.
You shouldn't be sharing that.
Despite my curiosity, I explicitly refused to agree to Apples terms for accessing those documents, because they were very draconian. The terms absolutely forbids using the information for anything other than optimising software for apple devices.
Discussing the design tradeoffs of RISC-V μarches couldn't be further from "optimising software for apple's devices".
> You shouldn't be sharing that
Ah, I suppose.
> On the other hand, if you want to fuse load pair on RISC-V you have the entire rename stage to figure out which uops can be fused independently of the rename stage
That's a good point.
If some RISC-V μarch was going to invest the extra gates for a complex fusion setup, the search isn't actually going to slow anything down, as it can run in parallel with other frontend operations (like renaming).
I always just assumed fusion was done as early as possible, only considering instructions that are right next to each-other (that's certainly the intent of the RISC-V spec), and then resolved immediately after decode.
But maybe it's better to do it right at the end of the front end; After renaming, during insertion into the scheduler.
> think a large part of the issue with RISC-V is that it predates (public knowledge of) ARMv8 by a year or two
Does it? https://people.eecs.berkeley.edu/~krste/papers/EECS-2016-1.p... has a section on ARMv8 (section 2.5)
It says they became aware of it a year after they started the RISC-V project, but that’s five years before that paper was published.
2015 is when it started to gain steam as a community run project.
But version 1.0 of the spec [1] was released all the way back in May 2011, and the first RISC-V chip was taped out at the same time. This is 5 months before ARMv8 was even announced, and we didn't start seeing actual aarch64 chips until late 2013.
And TBH, I'm not sure anyone realised just how good of an ISA aarch64 is until quite a bit later.
RISC-V 1.0 isn't binary compatible with modern RISC-V, they hadn't frozen the encoding, but rough design is all there.
[1] https://www2.eecs.berkeley.edu/Pubs/TechRpts/2011/Archive/EE...
Yeah...risc-v can learn from 50 years of x86 (among others). And yet.......
He has good points, except he misses the goal posts completely.
>I still do believe RISC-V did a lot of things better than x86...
Such as? I can't think of anything it does better for high performance cores.
1B through 15B variable length instruction mess, for one. Which still yields a worse than average 4-5B per instruction average.
That is a strength, not a weakness. It allows for things like 64-bit immediate loads, 32-bit branch offsets, and nearly unlimited future extensibility.
With RISC-V, multiple instruction workarounds are needed for all of the above, and those sequences are usually sequentially dependent ones so they can't be run in parallel. i.e. the insanity of loading a 64-bit value through repeated 12-bit immediates with shifts, using multiple instructions to compute branch offsets, and RVV needing setvli instructions everywhere due to not having opcode space to encode vector length/type.
AArch64 is better, but still has problems with limited opcode space when it comes to future extensions. They've had to make "start mode" and "end mode" for SME to save on opcode space, and future compromises will likely be necessary.
Always good to see stuff from Dmitry; his presentation (Linux/4004) at last year’s Teardown was awesome.
Is there a RISC-VI in the works where they try to learn from the RISC-V mistakes to make improvements?
Given the amount of learning that could have been done before RISC-V and wasn’t, I wouldn’t have such high hopes.
Considering just how many of the problems seem to come from RISC-V being a clean-sheet design, I suspect we would be better off not doing another.
What I am interested in is the idea doing an AArch64 style revamp of the ISA, were much of the non-encoding semantic stuff is kept, but the entire instruction encoding (plus all the CSRs, and other things) are reworked to be sane.
You might even do two reworkings in parallel, with one variable-width encoding optimised for microcontrollers, thumb-style; And the other being a fixed-width encoding optimised for wide out-of-order cores.
And at the same time, you make a bunch of extensions mandatory, and unify others into bigger chunks; Code compiled to one of these two encodings would know it had access to a much wider range of instructions.
The idea would be that any C code targeting RISC-V can be compiled to this encoding with close to zero changes, and that mechanical translation of exiting RISC-V binary code should be "possible", as none of the underlying semantics have changed. And the same would help any core wanting to natively support both (or all three) encodings, you would only need a front-end translator.
I feel like that's largely mitigated by profiles. RVA23 is really looking like it'll be the modern base target used for high performance application processors and it makes mandatory pretty much everything you'd want for those use cases, and other comments by people familiar with designing RISC-V CPUs mention that the variable length encoding can be dealt with in a very simple manner that doesn't even add another pipeline stage so it doesn't seem like it's all that big of a deal while also bringing in benefits in code size reduction. Not everyone is adopting it, but several major players have set the stage by mandating it.
Well, the revamp I’m suggesting would essentially be implemented as a RISC-V new profile, just with a different instruction encoding.
This and exactly this. If there is anything I learned in the past 15 to 20 years, I doubt it will be any different. The mentality of development is just different.
I want the iteration of the product that is in its 2nd or 3rd official iteration. Where you have a lot of learning done and battle tested. Preferably without the backward compatibility to create something truly beautiful. Would it be perfect? Of course not. But it will be Great.
I so wish ARM had some counter offering. They might as well give away their their low end design for free.
100% agree with dmitrygr.
I was excited when I heard about the project just after it started. However, past experiences taught me to wait before getting excited about the new 'shiny thing'. I did it differently with RISCV. I waited. I am glad I did. It took a long time for actual silicon to appear. Also, the silicon today has all the facepalming special cases mentioned in the article. Its almost like those old soviet era cpus that had the list of bad instructions handwritten on the package.
Overall, RISCV was a minor spin on MIPS, but without really learning from other processors.
So why is everyone still pushing for it? It has the words 'open' on it. People pattern match on that marketing.
As part of that marketing, they also pushed this attitude from the project... 'RISC won'. I think Chester Lam said it best when he wrote his essay stating that RISC didn't win... OoO archs won. I couldn't articulate that nearly as well as he did. If you haven't read it, I recommend it.
So, yeah, here we are. Many people will follow the bandwagon, but they will find that RISCV will not make a significant difference.
I am glad we still have Arm (in all its many forms), x86, and others. (btw, despite my username, I don't think x86 is the best either :-)
Also, if you aren't trying to ship a product, you can experiment with ISAs on an fpga. Yes, fpgas are a lot slower, but they are also a lot more fun. Especially with the great work done to create open source toolchains. Heck, if you are really serious (slighly crazy), you can build your own chip. For the foreseeable future ASIC shuttles are available at prices under $10k. (again, you have to be a little crazy)
> slighly crazy
What a lovely euphemism.
Signed: someone slightly crazy.
I'd say RISC won, when you consider how "RISCy" x86 is[1] compared to the ur-CISCs (68k, VAX) that RISC projects were in opposition to.
[1] Not because of often-called "risc like" microcode engine, but because the most complex addressing mode on x86 usually decodes two microinstructions, and decodes in single cycle. In comparison VAX needed separate pipeline for instruction decoding.
The two winning instruction sets are the RISCiest CISC, x86, and the CISCiest RISC, arm.
> In comparison VAX needed separate pipeline for instruction decoding.
That's how the VAX 9000 and NVAX did it. It's not the only way. It is absolutely possible to decode a number of normal VAX instructions in parallel using a pipelined decoder similar to x86 decoders. It is also possible to use a µop cache similar to many x86 and ARM implementations.
Fallbacks are only needed for the weirder addressing modes and for instructions that positively beg to microcoded (system calls/protection level transitions, some bit vector stuff, COBOL decimal stuff, block copy/scan/fill/compare, probably POLY) and startup and interrupt/exception handling.
DEC never did this but they absolutely could have.
X86 does not really need pipelined decoders like NVAX did. The complex decode for x86 is the fast path for NVAX without going into CSU. And CSU is where all the more complex addressing modes on VAX end up going - the complex instructions are executed, yes slowly, but in separate unit once CSU finishes the decode for them (and even for packed decimal stuff I-box can theoretically decode in nearly one cycle if all operands are register or immediate). uop cache I'd admit could help for some cases, but still leaves you with even a simple ADD instruction possibly expanding into ~7 uops, maybe 3-4 if we assume big fused equivalent of LEA but then 2 of those will still stall with memory requests.
DEC didn't try to parallelize the decoder further because it already could face 56 bytes for a single instruction, and the NVAX design was costly as hell. x86 in comparison has limit of max 15 bytes per instruction, and most instructions in x86 code fall in 4 bytes
> The second category for big-compute is actual desktops and SBCs that do interactive computation, browsing, gaming, and other such "desktop work". I do not expect RISC-V to be a serious player at the top of this market. Simply put, the architecture is not designed for it, as pointed out above. Additionally, this market has the margins to afford licensing a much-better-designed aarch64 core from ARM, and gain proper support from a much larger corpus of software. Before you get your megaphone to shout about "openness", please note that the openness of the RISC-V spec is not relevant here at all, because an open spec does not magically materialize a well-designed out-of-order core for you for free. And if someone were to design a good out-of-order core, they would not be giving it away for free. An open spec does not mean every implementation is free.
I basically disagree with this. Not because this isn't the current state of things (it absolutely is), but because we're at a bit of an inflection point where mooore's law has proved itself to be an scurve, and we're very clearly well into the top half of it. From that, gate counts per core will also start to ossify, and that means the longer latency for getting an open core design off the ground initially will also start to make sense.
Whom do you expect to work for free to design you a state-of-the-art core?
The same kind of people that 'worked for free' to develop Linux.
If those people build cores like linux kernel is built design-wise, i will PAY to watch the spectacle.
You do realize that Linux got basic SMP support 3 years after NT, and it was shaky for a while after? It still does not have reliable sleep-wake. And it only added native async file i/o in 2019, while NT has had it on the same hardware since 1993? So.. i'll expect an in-order core with an IPC south of 0.5 that cannot exit low power sleep 30% of the time in a decade or so.
> You do realize that Linux got basic SMP support 3 years after NT?
Linux started about three years after NT did. And NT could only support 64 processors for a long time when Linux could support thousands.
> It still does not have reliable sleep-wake.
Neither does NT really. Both depend on ACPI for the systems you're talking about, and it's the platform interface that's ultimately fucked.
> And it only added native async file i/o in 2019, while NT has had it on the same hardware since 1993
And has beaten NT on IO throughput for decades, and even now windows ships with a linux kernel integration because running Linux on a hypervisor is far batter for filesystem ops than running those on NT.
And the new async I/O API was so good that NT adopted it wholesale and didn't even bother changing the name. https://learn.microsoft.com/en-us/windows/win32/api/ioringap...
> So.. i'll expect an in-order core with an IPC south of 0.5 that cannot exit low power sleep 30% of the time in a decade or so.
There are already open source OoO RISC-V cores.
But the point originally isn't to be some Linux fan boy (I've written a decent amount of NT kernel code, and have a lot of respect for NT and the things it did right). It's to point out how the upcoming changes inherent to how chips are made and the latencies between gate count targets will better support open collaboration. And once that's supported properly, open source has a tendency to kind of snowball.
We shall see :) When my iPhone or laptop is no longer running aarch64, i'll happily admit i had been wrong
I mean, Apple is different from pretty much every other manufacturer here. They collborated in the design of aarch64, and a rumored to own a lot of the base IP themselves which they've cross licensed with ARM. It's very close to AMD:Intel::Apple:ARM when it comes to aarch64. That heavily changes the licensing costs. My point isn't that RISC-V is markedly better, but instead that it's equivalent from a perf achievable from in the same nexus of PPA and NRE effort. So there's no reason for Apple to take the pain of a leap with no real gain, but NRE losses.
I would expect to see RISC-V Android phones (probably initially out of China, despite ARM China) within the next few years. They've been busy bees since RVA23 was ratified with a bunch of Chinese companies making changes to optimize AOSP for RVA23. I've also heard on the grapevine that NT already has a RISC-V port internally, but take that with whatever grain of salt you feel like. But Microsoft has already been contributing to the RISC-V specs (they contributed to Ztso for instance).
There is zero chance that Apple doesn't have MacOS and iOS running on RISC-V in the lab.
They did that with x86 and Arm half a decade before any announcement about a switch, not to mention a number of other ISAs that didn't make it to shipping (e.g. M88k) and probably ones that word has never leaked about. IA64, anyone?
They're too large and rich and risk-averse to *not* do it.
I do wonder, which of the two of us actually worked for years in Apple’s kernel team? :)
Not me for sure. I have no idea about you. Of household name companies I've only worked at Mozilla and Samsung R&D. And SiFive if you count people in threads such as this.
I could of course be wrong but I think the publicly known history sets the pattern pretty reliably for the speculation.
FWIW, since OP was, well, the OP:
https://dmitry.gr/?r=01.Myself&proj=06.Work
History is much easier than prediction.
I'm with Jim Keller when he says that in time the fastest CPUs will be RISC-V ones.
If China leapfrogs EUV, this could happen.
What does this have to do with anything? You do know that a bunch of American corporations are shipping RISC-V cores, right? Including Jim Keller's current company, Tenstorrent.
Chinese scale is one way RISC-V could win. If China suddenly starts reaching <5nm process nodes at scale and uses RISC-V, they'd flood the market with cheap high performance RISC-V chips and probably start using them in their domestic Android phone market.
Linux is decent for its core use cases, but it is far from a solid pro-grade OS in a lot of areas... and in the areas it did get there, it took a long time to get there.
> but it is far from a solid pro-grade OS in a lot of areas...
Insane take given all the things that run on Linux...
It's server-grade. Not desktop-grade.
Tell that to Valve or the millions who use it as a desktop.
Also, have you used Windows recently?
I keep saying Linux can win on desktop by just sitting still while Windows sucks more and more.
Most Linux devs have been corporate employees getting paid to develop it for a very long time. It's not the early 90's any more.
That's why I put 'worked for free' in quotes like that.
The future set of people who once would have "work(ed) for free to design you a state-of-the-art kernel"? If the tail is long enough passionate hobbyists will do it because they love it...eventually.
I'm not sure the gate count argument works in RISC-V's favour.
While RISC-V is quite optimised for gate count for small cores; In large wide OoO cores the variable length encoding really bulks out the decoders.
You basically have the same requirement as x86, where you have to attempt to decode a 32-bit instruction every 16-bits (because there is no alignment guarantee for 32-bit instructions), and then cancel out the invalid ones. It's not quite a bad as x86, you only need to look at two bits, but it still forms a long dependency chain, and probably requires at least one extra decode stage with complex routing to pick out all the valid instructions.
You don't really have to have a separate decoder every 16-bits. What you have is a length decoder every 16 bits (so just a single nand gate over the first two bits versus a huge chunk of the prefix/opcode part of the decoder for x86), which then feeds into a set of muxes for the actual decoders. The actual increase in complexity ends up coming from the critical path of the stack up of length selection affecting start addresses (and therefore mux selections) for later instructions in the block, but even that's not nearly as bad as it sounds because you can use the same base trick behind a carry lookahead adder. When I did some experiments a while back, it ended up being less than half a pipeline stage overhead versus fixed width instructions kind of across the board.
So not nothing, but very far from a deal breaker even for wide 8, 10, or even 12 wide cores.
Yes... but then you are kind of wasting a pipeline stage on nothing more than length decoding.
I suspect a design with a full decoder every 16-bits might actually win on everything but gate count, mostly because it can deal with variable length instructions and variable number of μops per instruction in the same step. A decoder that doesn't output a μop because it was clobbered by a previous instruction, can be handled the same was as a decoder that didn't output a μop because of μop fusion.
Actually, that approach might actually eliminate the need for the extra pipeline stage (just at the cost of gates).
It's certainly not a deal breaker. But it's a valid criticism of the ISA.
I said easily less than half a pipeline not a full stage. Everything kind of shifts around a bit because of that, and it ends up being a pretty different design than a fixed width front end because of it (hence qualcomm's objections), but it's not clearly worse.
And for better than aarch64 density, it seems to make a lot of sense.
Ok, so you doubled the number of decoders, how is that not significantly better than x86?
I'm not even sure you have a point with regards to it being a valid criticism. Doubling the silicon area for instruction decoding probably costs nothing, because if you have a simple decompression stage, the maximum number of decoders is already doubled in the first place, because you're hypothetically encoding twice as many instructions to begin with. If you can double the decoders in the decompression stage, you can probably get rid of a separate decoding stage altogether and thereby reduce the cost to literally nothing.
Look, it might not be obvious but in university I once had to design an ASIP and then do the floor plan with Cadence and the area of the SRAM dwarfed everything to the point where my ASIP was a tiny vertical column in-between two SRAM chips. I personally was shocked by the fact that I struggled to even find my ASIP on the floor plan, because it was maybe ten standard cells wide in-between the SRAM blocks. Like, ridiculously tiny to the point where it is hard for me to even care about the area the ASIP took up.
> you can use the same base trick behind a carry lookahead adder
YESSSS.
I've been pointing this out for years and years.
By the point that you're looking at the same propagation delay as a common 64 bit adder you're decoding 64 chunks of 16 bits per cycle. That's 128 bytes, or a 32-64 instructions wide decoder.
That is so much wider than anyone is making or contemplating — or that even makes sense given the size of basic blocks — that it's just a non-issue.
And even if you go to those extremes, the biggest nay sayer says the cost of the design flaw will require you to double the number of decoders, which hardly sounds like a big deal to me.
It's not even double, because half of them are RVC-only decoders.
The annoying thing about RVC is that 32-bit instructions can now appear misaligned. I would be far less annoyed about RVC if it didn't break alignment, as you could solve the problem with a bunch of RVC-only decoders at the misaligned offsets.
So you either need (almost) double the number of full decoders, or a length decode and a bunch of shifters to get each decoder the right input bits (which get larger the wider the front end is. The 8th instruction can be at one of 7 possible offsets)
I don't believe this will impact performance in practice, because nothing forces CPU vendors to implement fast compressed instructions. If compressed instructions become slower than non compressed instructions as the instruction decoders get wider, compilers will stop emitting them in the future.
Nobody in high-performance does fixed-width instructions that allow lineary scaling parallel decoders. Arm basically requires certain instructions to be cracked into multiple uops before rename. That ends up analougus to decoding compressed instructions. RVC increases complexity before decode, how much that impacts things idk.
> […] we're at a bit of an inflection point where mooore's law has proved itself to be an scurve […]
Well. May's law[0], which states that:
effectively counterbalances Moore's Law and, with continued technological process improvements and optimisations, the proverbial arm's race is likely to continue for a very, very long time – just a few days I was reading a wonderful article from 1998 on the state-of-the-art DEC Alpha 21264 CPU which mentioned the 21264 and POWER3 as the world's most complex CPU's each boasting 15+ million transistors and also mentioned the equally state-of-the-art 0.18 micron processes. The 3 old year M3 Max design, in comparison, supplies over 90 billion transistors to the mainstream consumer.
Humans are resourceful, after all.
[0] https://en.wikipedia.org/wiki/David_May_(computer_scientist)...
That's sort of orthogonal to what I'm saying.
And the M5 doesn't have 500B transistors. We're well into the beginning of the ossification. Hell, it arguably started ~2006 with the end of dennard scaling leaving us with Tomasulo OoO cores being the design that makes the most sense for application cores, just getting wider over time as we get more gates.
Eventually CPUs and GPUs converge: huge numbers of CPUs with wide vector units.
I'm amused that the story doesn't even mention the 4k pages - way too small for anything but embedded systems today.
RVA23 hardware is available (e.g. SpacemiT K3)
Some are already on RVA23.1 even before the standard made it to more than 4 manufacturers product lines.
The meme joke about standards is sadly relevant for riscv. =3
https://xkcd.com/927/
As I’ve come to understand it, standards simplify intensionally, not extensionally. For those who select a part that is compliant with a standard, more standards to choose from is better because engineers are able to make better tradeoffs; they’re not forced to select a part that does way more than the application needs thus making the product more expensive if there are lots of “competing” standards: some do less some do more.
For RV, a litany of standardized modules creates a system where each capability that the module provides will have a standard interface. No manufacturer is forced to invent extensions bespoke to their implementation, but they’re not forced to support everything the most powerful models do either.
Just my two cents.
That is given, vendors actually _know_ what exact practical applications they are building for.
Sure, the constellation of features is no longer a general purpose computer in the retail context, but rather an ASIC appliance the ends up incompatible/useless rather quickly.
Maybe Gentoo could tame that level of chaos... or people just buy ARM64 again knowing the software ecosystem already works. =3
The RVA point releases don't add new mandatory features, so every RVA23 complient board is also RVA23.1 complient. They only add new optional extensions.
Until people admit they made the same mistake as ARM6 fragmenting the architecture focus, its adoption will probably continue to stall under each firms hubris. =3
https://en.wikipedia.org/wiki/Second-system_effect
So it's mostly the "Optionality". Like USB. And yet USB is everywhere...
And USB-C is known as a compatibility mess.
Is it though? Is it really? Outside the HN rant circles which want to return back to times where you needed an adapter for every single laptop model or be shit out of luck for connecting your mouse or projector?
yes, hope this answers the loaded question :)
MIPS or PowerPC is also free. We can use them too.
MIPS has switched to RISC-V.
+++
Excellent and well written description of the RISC-V ISA.
Refreshing style of writing. I know nothing about ISAs, but the rant was so fun
This feels like Andy Tennenbaum's LINUX is OBSOLETE post from 30 years ago.
don't see how? the last section is pretty explicit:
> None of this is to say that RISC-V is doomed. As I said, I fully expect it to take over the space currently occupied by [...] Much like the linux kernel -- the price is right.
Last section?! You think people actually read these before commenting?!
It's interesting that this quote closed it for you, because that quote is what triggered my take.
I read that as a hat tip to the legendary argument, and a partial adoption of Linus's rebuttal, “Linux wins heavily on points of being available now.” Besides the general tone, I guess.
> After being asked for the Nth time to explain, I decided to put it all down in one place so that I could simply link to it when asked next.
Bookmarked, because I've needed the same.
The worst part of all this is that they really should have known better by now. In 1980 you could make these kinds of mistakes, because this was pretty new territory. In 2020, doing this just makes you stupid. Or ignorant. Or both.
I’m not so sure - the 6502 existed in 1980 and showed the way.
6809 is a better exemplar, but, yeah, we knew this stuff way back when.
The problem is that everybody around RISC-V wants to sell IP instead of a chip. Most of the worst brain damage follows from that.
The rest of the brain damage follows from "We want to compete with ARM A-Series cores." No. Just ... no. Nobody willing to spend that much on a processor gives one iota of damn about ARM licensing fees.
So, the semiconductor market wants a cheap, consistent chip that operates in the deep embedded space while the RISC-V ecosystem considers the mere thought of that to be icky beyond reason. And China will push on this like Longsoon and pray that somebody figures out how to make it not suck (Prediction: they won't succeed.)
And, the worst part is that RISC-V has basically lost its window. The single possible advantage that RISC-V had was that as people converged to a shared tooling ecosystem it would create lockout. Unfortunately, that convergence never happened so, at best, we got some shared compilers. And, now, AIs can basically one shot all your other tools around it and probably the compiler not far behind. And there goes your ecosystem lockout.
Because selling "bits" is very lucrative, whilst actual hardware can lead to huge losses if it doesn't sell. Just ask Microsoft.
It's no wonder Microsoft is pulling out of the game console market and handing it over to PC manufacturers to make the actual hardware.
I think a lot of this criticism is completely true. However it's also overblown. I do think the ISA matters, but little mistakes like these definitely don't matter enough to preclude making M-series class chips. The reason it hasn't happened yet is simply time. It takes a really really long time to build up to that level of performance.
They've definitely gone overboard on the optionality stuff though. I don't think it matters too much for the actual CPU design but it makes verification and writing portable software a huge pain. Profiles definitely help but still...
Oh also I feel like you could probably come up with an equally compelling list about any other ISA. It's not like the fact that something has flaws means it's bad.
I don’t think making optional what optional features are available is a little mistake. It is a torpedo to the waterline.
It's not. In practice you have two scenarios:
1. You have a microcontroller. You're compiling code yourself and the docs tells you what features are available and which compiler flags to use.
2. You are writing application code. In that case you simply target RVA23.
The edge case is the same edge case where you use CPUID on x86, I.e. you want to target say RVA23 and RVA28 in the same binary. In that case you do have to use the OS APIs to discover what is supported... which is slightly annoying, but in practice you're just calling a different function.
In theory `mconfigptr` will eventually make this a lot nicer but nobody has put in the effort to define how it works yet (last I heard they were looking at ASN.1 sick emoji).
> You are writing application code. In that case you simply target RVA23.
You're allowed to not handle a majority of extant Linux-capable machines, but it seems like an awkward position.
When I looked into mconfigptr some years ago I thought it looked like a swirling vortex of pain that might produce something useful some day. Good to see it's still being worked on. Sad to hear ASN.1 is still involved.
I added an "misa but more bits" register to my core, using the bit assignment from the RISC-V C API, so at least until then I know what extensions each instance of my core implements. https://wren.wtf/hazard3/doc/#reg-h3.misa
Linux folks seem to have already put a lot of the mconfigptr info into the DT blob anyways.
Don't forget:
3. You are writing a kernel, with large amounts of inline assembly
4. You are writing a compiler, either offline or online
5. You are writing embeddable blobs that don't know what platform they will be running on.
6. You are designing a RISC-V core, and need to decide which extensions you should be supporting for your intended use-case.
ALL chip designs are an exercise of minmaxing these 3 variables:
1) power
2) performance
3) die area
SOME chip designs also care about a 4th:
4) die area.
NO design has the best of all...it is impossible since you have to trade 1 for another. The reason x86 has been dominate for so long is that is strikes a good balance across all areas, especially #4. A good balance is what you need for a good chip.
EDIT: oh and you can't beat the system I mentioned above. The laws of physics are the reason why.
You forgot the variable that RISC-V chose to maximize:
5) Weird principles that are completely detached from anyone's actual needs and that are carried to a length similar to religious convictions.
My biggest personal pet peeve about the architecture is the JAL instruction.
That is, PC-relative jump and link immediate, which jumps to an PC + sign extended immediate value and stores the address of the next instruction in a register. This is your most basic function call instruction. It only has an immediate range of 21 bits. Even a few bits scavenged from somewhere would really help it, ±megabyte of range is in the vicinity of what you need for internal calls but not generally enough.
It's a 32-bit instruction, so why can it only support 21 bits of immediate? Because the people who made RISC-V decided that implicit register arguments are works of the devil, and that you need to use any register as argument for any instruction. Therefore the RISC-V JAL instruction contains a 6-bit field for destination register, which is where they store the next instruction address. Never mind that there is not and will never be a compiler that emits anything but the ABI compliant return address register "ra" to that field, we decided we won't have implicit arguments so by god we are going to pointlessly sacrifice 5 bits⁰ of space in every single fucking branch, often forcing the user to construct the address in a register and use more instructions instead, which is much worse than it sounds, because branch prediction is easier for immediate branches.
This is not the biggest actual problem with the architecture. They added an instruction that adds upper immediate bits to PC, which the any core that implements instruction fusion fuses with jalr. But that sacrifices the low-end, that doesn't fuse anything, and uses two instructions for an extremely common pattern that everyone else manages in one. The reason I hate this one so much because there is no actual reason to make this mistake. A five minute conversation between two engineers should have killed this one in the crib, literally everyone knows not to do this. Apparently other than the RISC-V folks.
0: I give them one bit, because the opcode is short and they use the zero register to suppress the link and turn it into a normal jump.
https://github.com/riscv/riscv-isa-manual/pull/3269
Everything being an optional extension is covered by the article. It's bad enough for OpenGL and Vulkan but to burn that into silicon and not have a reliable way to detect them is way worse!
> So what does it even mean to comply with the spec then, if everything is optional?
Similarly, I kept saying it for long that a file/wire format's usefulness is not in what it supports, but in what it forbids. A binary file supports any type of data, but it's not useful.
Having written a few RISC-V cores, worked on a chip design project that used RISC-V cores, and generally being OK with the architecture in real-world use cases:
What the heck is this guy's problem? Just about every thing he mentioned as a problem is not a problem in practice. Too many options? Who cares, you're not trying to write code that runs on every possible configuration. Either you're writing embedded firmware and know exactly what core you're using, or you're writing an application that runs in an operating system and that system has a minimum ABI like RVA20 or whatever.
Array accesses take an extra instruction? Either you're in a tight loop walking a tiny array and you don't do the full offset calculation per step, or you're walking over an array in RAM and you're bottlenecked by the memory bus.
Hell, 90% of his arguments are "You can't detect X at runtime from user code without relying on some extension" - Yes, that is totally fine. Either you know your target CPU, or you don't - and then you ask your OS for details. This is not some dealbreaker.
From the article - "For example, if you are writing a kernel and want it to support all RISC-V cores" - NOBODY IS DOING THAT. You target a platform spec, not the combinatorial explosion of everything from RV32E to RVA22 or whatever the latest is.
You want to distinguish S mode from M mode? WHY DO YOU NOT ALREADY KNOW THIS?
Instruction encoding is weird? WHO CARES, the decoding is like eight lines of Verilog.
"Who can predict how their binary will act when a floating point store silently becomes a double-register move or a jump instruction, or vice-versa?" - THIS DOES NOT HAPPEN IN PRACTICE.
Guhhhhh, I don't get it. This guy has some vendetta and either has not shipped any risc-v code or is just in love with his own personal favorite instruction set.
Yeah the OP post read to me like someone throwing the baby out with three drops of bath water. If this was presented more like “minor gripes with risc V” I’m guessing I wouldn’t feel that way
The encoding being oddball does have some effects on linkers/loaders though I imagine?
Not that linking/loading is a super hot path people generally worry about.
It has an effect only in terms of how big an offset you can encode in a relative jump, the _arrangement_ of those bits in the instruction is irrelevant (and already abstracted away in the compiler/linker framework).
Thanks for this. RISC-V brings out the armchair critics for some reason.
> Array accesses take an extra instruction? Either you're in a tight loop walking a tiny array and you don't do the full offset calculation per step, or you're walking over an array in RAM and you're bottlenecked by the memory bus.
I'm not a hardware person, but whenever I look at compiler output I find computed index accesses all over the place in the assembly. This would suggest to me that at least compiler developers believe these addressing modes to be important.
> Yes, that is totally fine. Either you know your target CPU, or you don't - and then you ask your OS for details.
So then my code has to choose between being hardware-dependent or OS-dependent? That doesn't seem ideal.
> "For example, if you are writing a kernel and want it to support all RISC-V cores" - NOBODY IS DOING THAT.
I'd hate to live in a future where linux distros need to ship a separate kernel binary for every random combination of RISC-V features. That said maybe the run-time feature-detection extension will be so widely supported in practice that this wouldn't come up?
It's very common for embedded teams these days to support a diverse set of cores with a shared codebase, depending on the specific requirements of different products/systems. SoC vendors will often change cores between versions or product lines, and I might need performance in this one system vs specific interfaces in another. So even if I know what core I'm using today, I don't know what core I'll be using in a year or five. I may also be writing a library or other reusable component and have no idea what core will run things today.
Let's take the bitfield instructions the author complains about for similar reasons. If bfi/bfx takes multiple instructions, optimal structure packing isn't necessarily a win for performance or memory usage. The programmer needs to trade off how often the structure is instantiated vs accessed. Even they can make the right decision today, it might not be the right decision tomorrow. And if they get it wrong, that might not be apparent until later (when it will be somewhat obscured in superficial memory usage analysis). Or the ISA can get it right the first time and also make things easier for compilers/humans in the process.
I can easily imagine this happening. When you change embedded platforms, the typical approach is to take the existing system and compile it for the new platform without carefully revisiting every decision made in the old system. If one of your vendor blobs was specified for the old system and the new system is "similar", you'll just link it in and see what happens. The metadata in the blob will hopefully catch the issue at link time, but it was an avoidable error.
> If one of your vendor blobs was specified for the old system and the new system is "similar", you'll just link it in and see what happens.
And what if that blob has instructions your new core just doesn't implement? This problem has nothing to do with overlap.
Then it crashes in a nice, obvious way as soon as you execute one of them? Illegal instructions aren't usually that hard to debug unless they're related to memory safety issues.
Then you take an illegal instruction exception, and you have a choice to request a rebuild, patch it, or emulate it. (Yeah, sometimes the vendors just don't cooperate.)
Incidentally, emulating opcodes is quite often practical (unless the performance must not be affected), and is greatly helped by having the plainest, cleanest instruction encoding possible, and a well designed system register & exception architecture.
> NOBODY IS DOING THAT.
RePalm kernel is literally that.
This guy is weird: there is no perfect ISA, only compromises and tradeoffs. He is looking for _his_ perfect. Won't happen, unless lucky, namely your perfect aligns with RISC-V tradeoffs. There are also sweet spots, and I am writting RISC-V assembly almost every day and that "hits" them often. I currently use at 99.99% the core ISA (I have a few muls and divs here and there). I don't even use the bit manipulation extension...
There are millions of RISC-V chips out there. Performant microarchitectures are getting there, but the access to the latest silicon process is gated by the other ones, hogging production capacity (and they probably don't want RISC-V to "get there"...).
And most of all, hardware manufacturer/designers won't have a lawyer ringing at their door: this is so much critical, this will make them tolerate a lot of RISC-V tradeoff choices they dislike.
And ofc, big mistakes WILL BE MADE AND WILL HURT BAD. Expecting anything else is thinking like a teenager.
It seems the current biggest mistake is the compressed instruction extension. It seems the complexity it adds for high performance is not worth it (arm removes the thumb instructions for reasons). I have suspicions on some microarchitectures designed around the compressed instructions (16bits) having a negative performance impact on core ISA 32bits instructions (and many compiler optimizations are friendly to the way compressed instructions are, namely the destination register is one of the source register, that due to the legacy x86_64). BTW, Intel APX something, is basically RISC-V for x86_64.......
Another aspect people tend to forget while dealing with RISC-V, many of those design choices were made for the simplest way to implement performant CPU microarchitectures. Some say thats why on 'out-of-order' CPUs, you don't want a status flag register (there is none in RISC-V).
So … use RISC-V as the strawman, and create a community-based RISC-6 that doesn’t have these weaknesses? Better to get in now before it becomes too solidly entrenched.
You can't make a community-based ISA, it's not possible unless you have a community-based fab. He who makes the chips makes the rules.
I mean, a shuttle run is pretty cheap these days. If you have silicon, and customers, scaling past a shuttle run that worked is pretty low additional cost.
It's not really a community though is it?
Err … RISC-V is an ISA without a fab?
Likely impossible unless you somehow come up with something vastly better (unlikely).
None of these things are remotely bad enough to make the downsides of using another ISA palatable.
Anther ISA like ARM? It seems pretty palatable to just about everyone not academic.
The ARM ISAs are not free to implement. ARM holds patents relevant to the ISA.
Until the patents expire, which many have already.
The aarch64 stuff still has some time, particularly if you want stuff like virtualization.
You're vastly underestimating the amount of work that has gone into RISC-V that would need to be redone. It's not just a spec. There's an absolute mountain of software and hardware supporting it.
Sure. But … so was Linux, or Firefox, or GNOME or KDE, etc.
Even RISC-V itself was adopted by volunteers and supported by toolchains, and then kernels, and applications.
The amount of work is less a problem than the motivation. And motivation really just depends on recognizing that the status quo sucks, but is fixable.
And yet, new ISAs arise fairly regularly, for various reasons. RISC-V itself succeeded largely because it is gratis, I think.
How about EPIC-esque packet-based instructions?
64-bit instructions with 4 bits indicating instruction formats (60-bit, two 40+20-bit variants, 30+30-bit, 20+20+20-bit, three 30+15+15-bit variants, and 15+15+15+15-bit). Have each larger instruction type be a strict superset of the smaller instructions, but with larger immediates, more registers, and maybe additional instruction formats (eg, for SIMD).
Something like that would be even easier to decode (converting short instructions to long is simply a bit of wiring). Instruction density should increase due to 20-bit instruction type. Having properly-aligned instructions would help with fetching performance. Larger instructions means you can jump 4x further with the same immediate and 16-bit offsets. No need to have some of the V extension workarounds (from not wanting to add 48-bit instructions).
So a VLIW, interesting but usually compressed instructions are at most two-registers..
Not traditional VLIW per-se as packets wouldn't imply parallelism (though that's theoretically possible) and instruction count would vary.
2-register to 3-register also just involves different wiring and costs nothing. I think you'd see 15-bit stick with 2-register. 20-bit would more interesting. You could choose to spend 3 bits on a third register or you could widen 2-register instructions to access the 32 core registers (or something between where you do 3-register, but only on 16 registers). 20-bit also reduces some of the need for very large 15-bit immediates (especially jump which is upward of 10% of the total space on 32-bit designs) which could allow more 15-bit instructions further improving effective density.
Easy access to 40/60-bit instructions mean stuff like vsetvli could simply go away and very useful instructions like FMA4 (instead of FMA3) could be added. Vector masking is another big one. They don't have enough bytes for a full vector mask set resulting in some hacks.
The big question is about jumping and predicting inside packets. You can add 2 bits for what externally looks like 16-bit addressing (where the 2 bits indicate packet position to jump to) or have faster jumps that always hit the beginning of the packet (at the expense of code density due to nops). There might even be a hybrid approach where short jumps can jump within a packed, but long jumps must jump to packet boundaries (which makes sense as most compilers make functions align on cache line boundaries anyway). There is a point for eliminating 20-bit (and all that compression goodness) for 45+15-bit pairs instead) as branches inside packets are immediately calculable.
One thing I noticed with your clever encoding is that you can avoid some nops: instead of having 2 15 bits instructions followed by two nops, you could have two 30 bits instructions, saving maybe a little decoding energy.
Also the 60bit format will really help for loading immediates..
That said I wonder why normal ISA do not contain a 'Load Immediate on Next PC'? And if you want to allow parallel decoding the first byte of the immediate would be a 'special noop' and the first immediate byte would be inside the Load Immediate Next PC instruction instead.
I think this has to do with parallel decoding. How do you tell that the immediate is an immediate instead of an instruction? You have to carve out a very large part of the encoding space and you still can't fit a full immediate (eg, if you decided that all instructions starting with 1 were immediates, you'd be dedicating half of your encoding space to immediates and still be one bit short).
RISC-V does a 20-bit LUI (load upper immediate) then a 12-bit addi to the same register for the lower bits. Having access to 40-60 bit immediates makes 32-bit immediates a lot easier (with 64-bit immediates being multi-step, but quite uncommon).
> What does a cheap microcontroller core need? Let's inspect what they are used for. Typical use cases are to interface with and quickly reconfigure hardware blocks in a larger chip, eg in an MP3 player, an SD card, or a USB stick. The hard work is done by custom IP and the CPU core is just there to occasionally prod a register or configure something.
He forgot electronic cigarettes (vapes)
My apologies. I’ll update my shitpost with this example. :)
I wonder if they will be inviting him to the next RISC-V design committee meeting.
For a friendly meeting, like Julius Caesar had on March 15, 44 BC.
"This time its different".
If only ISAs weren't protected (or protectable) by patents.
I wonder how many of the obvious design shortcomings in RISC-V are from IPR avoidance / making IPR problematic parts optional.
When writing a spec, every single thing you make optional, you split the possible implementations into two incompatible groups. Do this enough times and you end up with your spec being meaningless.
I felt that.
What I like about RISC-V is not the ISA per se, but the ecosystem that has developed around it, particularly Chisel and CIRCT.
Specific choices for instruction encoding is less interesting, especially in the age of AI.
Things are generally defined by the neccessities that led to their creation. x86 was designed for home PCs and has been forced to evolve with PC technology. ARM was designed to take advantage of RISC architecture, and were forced to evolve with the mobile industry. What was RISC-V invented for, and what external forces have acted on it since then?
Ah rants from a non designer. So Patterson and crew, don't know what they are doing? Yeah hard pass.
What happened to the Rivos accelerator cores?
Meta acquired Rivos last year.
They got bought by Meta who then fired half of them.
always a winning strategy...
Thanosbook
It's clear that RISC-V started as an academic exercise (albeit from a group with esteemed credentials) and they had to bolt on these hacks to make it work in industry.
Sad.
ARM was also rooted in an academic exercise. A lot of the drawbacks for modern ARM PC platforms stem from the aversion to actually advanced features like SVE/SVE2 and UEFI.
It's sad, but it was also wildly successful. RISC-V has already replaced ARM in highly-custom embedded spaces like Nvidia's GPU controllers, and it likely won't stop unless ARM finally changes their tune vis-a-vis licensing.
> ARM was also rooted in an academic exercise.
Where do people get ideas like this from? Just nonsense.
ARM, the ISA, is wholly rooted in academic exercises like Berkeley RISC.
What do you think happened? RISC-I and RISC-II never existed, ARM means "Automated Reasoning Mechanism" and the ISA was never RISC whatsoever?
Talk about nonsense, damn...
"What range of offsets can a 16-bit instruction encode? Zero through three. Not thirty three, not three hundred and three. Three! Well, maybe it is better for storing a halfword? Nope... zero or two. What even? Why" What the fuck is this criticism? Its sanely specced, who would want arbitrary unaligned offsets, like for anything? Supporting such obscure idiot cases is too much unnecessary pain, so cut it off on spec level