RISC-V: The Last ISA?
thechipletter.substack.com
thechipletter.substack.com
Can it replace ARM? maybe in some roles that only require core features.
Will it become the popular standard? probably not, as the groups failed to learn what ARM did wrong. Most popular ARM cores have many advanced features disabled in the compilers for a few reasons:
1. Some ARM ASIC advanced features would err on some chips, or were simply unavailable on some silicon revisions.
2. Deploying chip specific compilers is unsustainable commercially when your competitor can port in billions of dollars of work with gcc (as bad as it is)
3. a complete RISC-V implementation with floating point and DSP extensions should have been the minimum core. Without these features, it dropped the whole generation 1 chip hardware into the low-end mcu domain. A saturated market, that has already fragmented.
Is there possible solutions?
Complete a fully open 64bit core with mmu, fpu, and DSP. Then give the design to companies that have had a proprietary hardware issue for decades like microchip.
Allowing companies to make proprietary design variants was a mistake.
Happy computing =)
Is it really that prohibitive to have your own custom compiler with LLVM (and CLANG)?
When running in multitasking environments it doesn't really matter. =)
There is a deep rabbit hole here, that touches on clocks/hardware/schedulers like RTLinux OS/RTOS/compilers. I am the wrong person to teach you this subject. ;)
RISC-V actually has a better story here. You basically have RV32IC (compressed will always be there outside of extremely niche chips because 400 gates for 25-35% smaller code saves more in RAM/ROM than it costs). Optionally, you may have Zmmul for only hardware multiplication or M for both multiplication and division (shouldn't make a difference outside of the size of the software routines if they are needed).
On the desktop side, There are only two profiles that would actually be used -- RVA20S64 and RVA22S64. By the time actual desktop processors are finished, RVA24S64 will likely be around and make a couple optional extensions required.
https://github.com/riscv/riscv-profiles/blob/main/profiles.a...
Ultra-tiny cores using the still not finalized RV32E may exist in the future, but a company choosing them would know full-well the tradeoffs they were making.
The only poorly-specified area is DSPs, but that's a problem for the entire DSP industry. There are a lot of requirements from the barely-DSP up through units doing a lot of signal processing. On the whole, I'd prefer to look at a handful of letters than have to dig through hundreds of pages of esoteric manuals.
The problem with such instructions has always been how to get compilers to leverage such feature automatically (see 30 years of GPU kludges). Perhaps some sort of standardized static library template could create/emulate a set of abstractions for the special opcodes within regular compiler contexts (i.e. still cross platform compatible like OpenCL, and hides the ugly inline assembly during binary optimization).
"RISC-V actually has a better story here", Time will tell, but we have all seen a lot of "better" cores disappear over the years. ;)
1. Identify high-level language output greatest common sequence in binary image code regions
2. Check if that sequence profiles in the top CPU usage of generic processes
3. optimize that sequence in the languages
4. verify improved performance
5. repeat until you reach the no-op delay loops
6. Add optimization in the compiler
7. verify improved performance with sub-optimal original language samples
8. add optimization to ASIC
9. replace optimizations in the compiler with new opcodes
10. verify improved hardware performance with sub-optimal original language samples
With RISC, many argued such processes were unnecessary, as every complex op can be emulated in simple code with a faster CPU. This ignores that fact Moore's law is effectively dead.
It wasn't ignoring anything. Moore's law wasn't dead at the time, and awareness of it very much informed the development of RISC.
Enhance your calm. =)
Have a great day. You're the best. Peace and love.
Patents prevent others form parenting it, even if prior art exists someone can still get a patent and the legal battle to revoke it can be costly if you don’t have large corporate backing.
So getting patents and offering them under an open FRAND license is a good option, some of the most common standards we have work this way.
Ofc if the only reason you get patents is to commercialize them later it’s going to be quite hard to get people to adopt your stuff.
Reminds me a bit of Transmeta. "Code morphing" sounds very much like the instruction reordering that's standard now.
Doing an emulator/JIT at this level has some severe problems & a very sketchy security story. It's unlikely that anyone else wants to do this, and "AOT" solutions like Rosetta 2 are almost certainly the better approach to ISA flexibility.
My bread and butter work isn't very close to the metal, but you sound more experienced with this sort of thing. Are you familiar with the mill? Do you think they have a chance of avoiding the weeds that Transmeta got stuck in?
Maybe all of that is solvable in some way, sure. CPUs can communicate with the kernel through various mechanisms of course, you can build it such that the JIT is a different task somehow that's observable & preemptable, etc... But it's complicated & messy. And very complex for what a CPU microcode typically is tasked with dealing with, for a benefit that seems quite questionable. It's not like there's any reason a CPU doing the JIT is going to be more optimal than the kernel/userspace doing the JIT - it's trivial (and common) to expose performance counters from the CPU, after all.
That doesn't mean a CPU designed for a JIT is inherently bad, it just means doing this at the microcode level like Transmeta was doing is a bad idea.
On another note: does anyone have experience with a RISC-V board you can actually order right now?
Unfortunately neither features the vector extension.
https://wiki.pine64.org/wiki/Ox64
https://liliputing.com/visionfive-2-risc-v-single-board-comp...
[0]https://www.clockworkpi.com/product-page/uconsole-kit-r-01
It's fun to mess around with.
So the main ISA will be little more than a distribution device for allocating tasks to subunits, and no-one will care how it's put together.
But I'm no expert.
So while we can continue to squeeze more onto a smaller die, providing more capabilities on the same processor looks like it will win out for some time yet.
I'm thinking of them all on a chip (or even same core) with external DRAM shared, and cpu cache shared.
> and having them share memory has all the common problems with race conditions and cache invalidation
That's pretty well a solved problem, or modern OS's wouldn't work.
> providing more capabilities on the same processor looks like it will win out for some time yet
I agree, for now, tomorrow's cpu will look like today's. But further out, I expect my view might perhaps start coming to pass.
GPUs seem to on the right path here as the trend toward a thread manager sending data to various CPU/ALU/SIMD/matrix/whatever units.
But if you insist, TI has some DSPs where CHAR_BITS is 16. They're supposedly a massive pain to use because you have to mask off the upper octet every so often.
But why?
I don't anticipate we'll ever stop caring about using RAM efficiently, so I assert we need a way to operate on smaller types. The compiler could provide the traditional API I want this by masking/shifting without instructions specifically for smaller types, but (a) then there's a lot of extra masking and such to do anything, and (b) it would be bad for thread safety. IIUC Alpha was a bit like this in that read-write operations done from different threads on adjacent bytes within a word might clobber each other. Not great...
And as colejohnson66 said, there are DSPs like this, but they are explicitly not designed for general-purpose programs.
I am ready for the successor, Risc-6, already. It can retain most details of RISC-V while fixing its more glaring deficiencies. It is not a mistake to optimize an ISA for use in undergraduate courses, but probably is one to use identically the same ISA industrially.
I don't know if the worst deficiency is the need to fuse up to 5 consecutive instructions to get useful operations per clock cycle to a competitive level.
While fixing serious problems, numerous smaller incidentals could be patched, such as having chosen the architectural representation of "true" to be 1 instead of -1.
x86 has at least ~1,000 instructions,[0][1] maybe more depending on how you count. I can't believe RISC-V will approach that number. I couldn't easily find how many instructions arm64 has. But you may be right about RISC-6, only I think any "RISC-6" will just be RISC-V with less useful instructions depreciated
[0]https://www.unomaha.edu/college-of-information-science-and-t... [1]https://fgiesen.wordpress.com/2016/08/25/how-many-x86-instru...
And since Intel locked AVX-512 out of alder-lake processors, if you want a consume grade processor which supports it you would buy a Zen4 from AMD.
This paper seems to say there are thousands, am I reading it wrong?
>There are two primary barriers to producing a formal specification of x86-64. First, the instruction set is huge: x86-64 contains 981 unique mnemonics and a total of 3,684 instruction variants.[0]
All that stuff is spelled out in the instruction and while it may have the same mnemonic, the actual binary output is different. In these terms, the actual number of instructions is likely in at least the tens of thousands.
In comparison, RISC-V splits off loads and stores into separate instructions. It further splits off each size of load/store into even more instructions. Start clumping all of this stuff together and RISC-V instruction count would also plummet.
[0] https://stackoverflow.com/questions/61048788/why-is-mov-turi...
The set of RISC-V features that each CPU supports is going to be so widely varied that you will need dozens of compiler switches to make full use any processor, and since most software will be compiled for the lowest-common-denominator, some capabilities will go largely unused. This is already the case with x86 with AVX-512, the full capabilities are only leveraged in specific workloads.
Either that or developers are going to rethink the way they distribute software. No longer as compiled binaries, but as an IR which is then compiled on each processor, since the best way to learn what features are supported by any CPU is to query them on it.
I guess it is time for another great idea for VCs, I know, let's create a WASM runtime for RISC-V.
The PPC approach works, but it has significant performance costs over and above instruction emulation. I've shipped PPC software that you may have used that uses both approaches, as appropriate.
Its possible we know each other IRL... lol
Oh the things I've shipped...
Which actually given the toy CPU's i've implemented is pretty easy to do even if your talking something that fits on a small/medium sized FPGA.
Illegal instruction traps are a lot worse/harder to get right than just cracking an unsupported opcode into a string of microops, particularly if the arch has simple addressing modes that themselves won't ever need to be part of multiple micro ops. AKA you won't have to deal with fault handling in the middle of a sequence. And even worse, the optimal sequence is likely diffrent for every tiny micro arch change, or even change in memory subsystem characteristics. So it needs to be tied to the core and associated memory subsystem, which on a popular arch implemented across the scale of platforms you find x86/arm is going to be unachievable without lots of unoptimal code being used.
This kind of approach has been used in the past, but the problem is that the overhead of trapping invalid instructions is massive compared to almost anything you do in an instruction, to the point that if you actually use such instructions, your program will be completely unusable on platforms that don't provide them.
There are a lot of problems doing it that way too, particularly if your on a small microcontroller with limited ram.
It can be done at the OS kernel level, but it does not have to. The usual place to do it in is libc – by virtue of weak symbols in dynamic libraries.
At the linking time, the ld links the executable against a generic function, e.g. __mul512_xyz, and __mul512_xyz is a weak symbol that points to a generic fallback implementation of the 512-bit wide operation in libc.so. Now, at the process startup time, the libc initialisation code looks up the CPU revision, attempts to locate a CPU revision specific, optimised version of, e.g. __cpu_family_abc_123_mul512_xyz, and links the optimised version of the function in. I have made names up but, fundamentally, the idea is that.
> […] this would allow program authors to choose whether to favor the least common denominator
… and this is where I perceive a problem with RISC-V – based on my current knowledge of the ISA in question. Being an open source and a free ISA, RISC-V places no obligation on two (or three, or more) distinct CPU vendors to implement the same set of ISA extensions (other than the foundational one). Therefore, effectively we are talking about every possible permutation of all current and future, extra, ISA extensions that would have to be supported in libc, and it will make it the dynamic re-linking at the runtime either difficult or not possible (not easily, anyway), and the RISC-V specific optimisation effort(s) will go out of the window.
For example, the RVA22S64 means it's a 64-bit application processor with supervisor mode complying with the 2022 recommendations. It has a bunch of specific requirements about RAM layout, cache instructions, being little-endian, and so on all specified so code is portable. Likewise M (mul/div), A (atomics) F (32-bit float), D (64-bit float), C (16-bit instructions), and some misc bit manipulation and other instructions MUST be implemented.
At the same time, it specifies optional extensions like V (vector), Zfh (16-bit floats), scalar crypto, H (hypervisor), and some optional supervisor stuff.
If you want to claim to be a RISC-V chip, you MUST implement the specs exactly (else be infringing on their trademark).
If you want to enter the desktop ecosystem that is being started, you'd better support the extensions they specify in RVA22S64 (or newer standards) otherwise people aren't going to buy your chip. You can implement proprietary stuff provided it doesn't conflict with the standard, but normal software isn't going to use those features, so you are probably just wasting transistors.
All the work on unifying stuff like UEFI is because the companies involved are serious about a compatible standard moving forward. It's in all the biggest player's best interests to stick to the spec which is all that matters for end users as it guarantees a consistent experience.
https://github.com/riscv/riscv-profiles/blob/main/profiles.a...
It is the optional extensions that concern me the most, not the foundational ones. Cryptographic functions, for example, can be optimised using a vector instruction set, a crypto accelarating instruction set, or via a combination of both. If something better comes along (hypothetically), it will become another, new, instruction extension in the future. The libc runtime now has to do significant guess work to support a permutation of all available instruction extensions (or fall back to a generic, unoptimised, version when none are available), not to mention the libc blowing out quite substantially for RISC-V – in size and in complexity.
> If you want to claim to be a RISC-V chip, you MUST implement the specs exactly (else be infringing on their trademark).
I admire your sense of optimism, but I can nearly guarantee you that a less diligent Chinese RISC-V vendor will not give a flying fig about the trademark and will even cut those extensions out that form the foundational set – if it makes the chip cheaper to design and manufacture. Which has happened in the past with some ARMv7 (or ARMv8?) designs, and which we are nearly guaranteed to see in IoT devices (at the very least). I will not be surprised if a CPU vendor chooses to toss the D extension out and stick with the F extension only for niche case solutions, and it will not be possible to enforce it.
Who cares. Is HP going to buy a cheap Chinese chip that causes user software to randomly crash?
If that company is going to compete, maybe they want a 5nm chip. They design the chip and get past sanctions, but now have to pay a half-billion to get everything ready for fabrication and then another 2B for that 100k wafer discount.
Now they have huge quantities of chips that are too expensive for the Chinese market and too broken/incompatible for the American/European market. Sticking to the spec -- even if it's just microcoded -- is way better than the alternative.
> It is the optional extensions that concern me the most, not the foundational ones.
Crypto is optional because they believe scalar crypto probably isn't the way forward. They are working on vector crypto, but it's not finalized. Likewise, the vector extension was released too close to the 2022 deadline to force compliance. Look at web standards. Where backward compatibility matters, it's WAY better to be conservative than to mess up forever.
RISC-V chips with decent performance likely won't be out until 2024. By that time, these extensions will be well-established. Companies will have had time to implement them and they will become required.
> I will not be surprised if a CPU vendor chooses to toss the D extension out and stick with the F extension only for niche case solutions, and it will not be possible to enforce it.
This is a particularly unlikely outcome because JS support requires double-precision. Even tiny ARM cores in phones over a decade ago had support for 64-bit floats. If you want to save area, cutting cache or wider SIMD gets you way more bang for your buck.
x86 has about 35 new extensions in the last 20 years excluding AVX-512 which adds another 20 or so.
It's also no different from ARM where you have (currently in widespread production) ARMv6, ARMv7, ARMv8 32-bit, ARMv8.0, 8.1, 8.2, 8.3, 8.4, 8.5, 8.6, 8.7, 8.8, ARMv9.0, 9.1, 9.2, 9.3, and some ISA extensions that don't fit neatly into ANY of those. Then ARM also announced (no doubt due to pressure from RISC-V) that custom instructions are also allowed.
This is effectively a solved problem for ARM and x86. It will be even less of an issue for RISC-V.
Even just taking RV32I, you have M, A, F, D standard extensions which are all optional. A CPU could include any combination of these, so you have 3! possible instruction sets off the start line. But let's assume we're working with G (which means all of IMAFD)
Many PC grade processors will support some or all of extensions B (bitmanip), T (transactional memory), P (packed SIMD), V (Vectors), C (compressed instructions), RV64I, RV128I, Q (quad floats), and not to mention all the non-standard extensions.
See: https://groups.google.com/a/groups.riscv.org/g/isa-dev/searc... for non-standard extensions.
You also have vendor specific extensions such as those from Huawei: https://github.com/riscv/riscv-code-size-reduction/tree/main...
As an application developer, finding the right set of features for your users will mean having to distribute many different binaries unless you stick to plain old RV32G, which has the capabilities of a ~20 year old x86 processor.
If you assume all standard extensions, it only takes a processor to lack 1 of them for the program to not work.
You can test for feature sets before running any of these instructions, but this is more commonly done at compile time via the preprocessor. This is what I mean about developers changing their perspective. It will be necessary to move all of those #ifdef __FEATURE__ to runtime, unless you recompile on each processor.
Do you mean RV64G? Linux doesn't really support 32 bit anymore. Even then the VisionFive 2 supports rv64gc And the whole board sells for ~50 USD. The d1 supports RV64GCV (admittedly v. 0.7) and sells for even less. I don't think any Linux CPUs will skimp on C and most will have V and B in my opinion.
Assume RVG64GBCV, do we skip P, T, Q? What about J (extensions for dynamic language runtimes)? Do we just ignore those capabilities and leave applications to not get the best out of the machine?
If we stick to current status quo, of having #ifdef __FEATURE__ scattered through our code, we would want a source based distribution like Gentoo to make sure we get the most out of our machines, so we can check which features are present and set all the required compiler flags.
Otherwise, we could have runtime checks for features, but this will require changing the way applications are commonly written, because we don't want to be checking for the presence of features everywhere in code. We only want to check once on application startup.
If you want people to use your chip in an interchangeable way (how ALL desktop processors want to work), then you'll implement RVA22S64 which automatically requires you to support a bunch of extensions.
If you want proprietary or cutting-edge extensions in your chip, feel free, but software developers will be using the spec and your extras will just be ignored and drive up your cost for no real value.
If you violate the specs you claim to support, you are liable for trademark infringement as use of the trademark requires adherence to any standards you claim to be supporting. At most you could claim "RISC-V compatible", but that will just become code for "doesn't work with normal software" and nobody will buy your chips and you'll have wasted a huge sum of R&D money.
This is better than x86 or ARM which you conveniently ignore. x86 for example has some 55 extensions released in the last 20 years. Some like SGX or FMA4 only have support of a small subset of chips. Some have disappeared. Many aren't supported by older chips still commonly in use. ARMv8 has TEN different version PLUS more optional extensions PLUS the ability to add custom instructions. There's also FOUR versions of ARMv9 too (leaving aside the still very popular ARMv6 and v7).
If fragmentation were such a huge problem, then certainly nobody would be using these ISAs. Of course, people use them everywhere which completely disproves your argument.
https://danluu.com/risc-definition/
Number of instructions isn't what is "Reduced" in RISC, but rather the complexity of instructions: Single-width opcodes with very few addressing modes, such that pipelining is easy and taking exceptions is not as painful as it is when your opcodes have lots of ALU state, like with indirect addressing and opcodes that mix addressing modes with their own ALU operations.
RISC is also somewhat nebulous, with some ISAs being "more RISC" (RISCier?) than others, and some RISC ideas (architectural delay slots, integer multiplication and divide opcodes requiring their own registers) eventually getting dropped entirely as chip technology moves on.
> It is not a mistake to optimize an ISA for use in undergraduate courses, but probably is one to use identically the same ISA industrially.
I don't know that a good ISA needs to be optimized for undergraduate courses to be used in them: MIPS is famously used in H&P and it has quite a following to this day, just not on the desktop or in servers. Was RISC-V optimized for use as a "model organism" like that?
I don't know if you could say RISC-V was optimized, as such, for undergraduate courses, but historically that was its design target. That said, there was a lot more attention to extensibility via regularized instruction set extensions than the undergraduate target demanded.
RISC-V's permanently-zero register is akin to other RISCs' special multiplication registers.
What issues does that cause? Finding it difficult to web search for…
I think this is not only correct but in a way almost obvious. Now that RISC has decidedly won out over CISC, well, what does RISC imply? To reduce the number of instructions to the minimum (or more accuratly to min/max the number). What we are left with are ISAs with few total instructions. This basically limits how much room there is for improvement, and the core instructions do not really change across modern RISC ISAs. In result, the best feature of RISC-V is not any technical feature but it's licensing features. If it gains mass adoption, nobody will ever switch to anything else because the ISA isn't the bottle neck of CPU performance anymore. A potential new ISA would have to have a different market such as GPU or ML to succeed.
Like when you look at the SIMD implementations on x86 "CISC" machines they're all load/store based instead of register/memory based like on the scalar and x87 implementations.
This is what people mean when they say RISC has won.
work/second = work/instruction * instructions/cycle * cycles/second
The "reduction" in RISC was in work (and complexity) per instruction, enabling even greater gains in the other two factors. I'm well aware that this isn't the official definition, but IMO it's the perspective that has held up best through all the intervening years. Load/store is certainly part of that. So are orthogonal instruction and register sets, exposed pipelines, software TLBs, etc. We've gotten away from some of those things nowadays, but in the early days they were necessary to drive performance despite lower work per instruction.
Oh boy. Good old branch delay slots on the earlier MIPS architectures.
Can you give the number of x86_64, ARM64 and RISC-V instructions? I didn't think ARM64 had 1000s of instructions.
In case it's still not obvious: PowerPC is obviously a RISC ISA, but it has just as many instructions as some CISC ISAs out there. Meanwhile PDP-8 has 8 instructions, but it's clearly a CISC ISA.
Consider if you want to load a 64-bit immediate into a register under the current RISC-V spec. Takes so many instructions that it's easier to just load a constant from memory, despite memory access being much slower.
lui r1, 0x01234
lui r2, 0x89ABC
addi r1, 0x567
addi r2, 0xDEF
shl r1, 32
or r1, r2
24-bytes, 6 instruction cycles and 2 registers.In x86_64:
movabs rax, 0x0123456789ABCDEF
11-bytes, 1 instruction cycle, 1 register.Note that while the performance effect of L1I cache misses is negligible, the complex x86-64 decoder may not be. Some SPECpu2017 have front-end problems due to the x86-64 decoder.
Another interesting metric is that x86 average instruction length is 4.25 bytes[0] which further implies that x86 instructions are only getting longer as time goes by. Meanwhile, RISC-V should continue to get more dense as new instructions are added.
Has it? The modern "RISC" designs out there in the wild include a lot of pretty specialized instructions.
I would agree load/store has won over instructions with memory side effects common to many CISC setups. Keeping side effects to a minimum to improve out of order and speculative execution has been a key goal of most modern ISAs, but keeping instruction count to a bare minimum has not. CPUs have landed in a space between RISC and CISC where simplified and reduced instruction count is certainly a goal, but the ISA will happily toss in a specialized instruction where significant speedup can be achieved.