7 ms·
The number of instructions is already becoming quite large if you consider the V and P extensions. Here's the vector instructions: https://github.com/riscv/risc
by sparkie 4y ago
The number of instructions is already becoming quite large if you consider the V and P extensions. Here's the vector instructions: https://github.com/riscv/riscv-v-spec/blob/master/inst-table.adoc https://github.com/riscv/riscv-v-spec/blob/master/inst-table...
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.
- pjmlp 4y agoThat is how mainframes and micro-computers have been doing since forever. I guess it is time for another great idea for VCs, I know, let's create a WASM runtime for RISC-V.
- addaon 4y agoOr OS authors are going to have to rethink how they handle illegal instruction exceptions, by patching the calling program to call into an emulated version when running on hardware that lacks support; this would allow program authors to choose whether to favor the least common denominator (and give up performance on more capable processors) or to target best possible performance (but take a hit on more limited machines). An ABI that reserves a few registers for this sort of emulation, or a couple or reserved architectural registers, could help a lot.
- pclmulqdq 4y agoNobody is going to be patching calling programs like this. There may be OS emulation in machine mode (saving and restoring the register file) to pretend to be a "generic" RISC-V.
- StillBored 4y agoI don't think he is suggesting patching individual programs PPC for example simply faults and traps to the OS for any number of illegal instruction or invalid alignment situations (which may vary based on core implementation). Then the kernel looks at the faulting instruction, emulates it, and resumes the program. Its absolutely terrible for perf because all the internal state has to be serialized to the architecturally visible state in order to update it, and resumes.
- addaon 4y agoNope, I was very much suggesting the former. 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.
- StillBored 4y agoEek, at that point you might just as well try and ship an IR with a JIT/AOT type pass during install, first run, etc. Its possible we know each other IRL... lol
- addaon 4y ago> Nobody is going to be patching calling programs like this. Oh the things I've shipped...
- StillBored 4y agoOr you know, you mandate most of the stuff in the core arch document with the assumption that on tiny cores that lack.. say multiply instructions its handed by.. wait for it... microcode. 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.
- addaon 4y agoMicrocode is an option here, but (having also implemented small microcoded cores on an FPGA) it's easy to be misled about ASIC costs here. ROM on an FPGA is very cheap proportional to logic, because it's implemented in various high-density (compared to the LUTs) memory blocks. A very small RISC-V ASIC implementation can easily be smaller than the ROM that would be necessary to microcode a complex ISA extension, ignoring the cost of the sequencer, while the same design in an FPGA might have zero change in area for the ROM.
- bpye 4y agoOn RISC-V it doesn't have to be true microcode. You could trap and emulate in M mode, transparently to the running OS.
- Tuna-Fish 4y agoThis won't work, because the emulation will be too slow to provide usable fallback. 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.
- addaon 4y agoThe suggestion isn't to implement, say, Vector Add in an illegal instruction handler; instead, it's to use the illegal instruction handler to replace the Vector Add instruction with a jump to a user-space emulation routine. The emulation routine may /also/ be too slow to be usable, but the trap overhead is a once-through cost, not a per-execution cost.
- StillBored 4y agoDoable, but you end up having to generate a unique sequence for every single instruction in the program because for something like 'mul r1,r2,r3' your going to have to move the information about which registers are being multiplied somewhere else, as well as encode the return address, and as you mentioned the register spill/etc is going to be costly or you have to reserve a couple registers for it. There are a lot of problems doing it that way too, particularly if your on a small microcontroller with limited ram.
- pencilguin 4y agoIt is a good way to turn optimizations into gross pessimizations.
- inkyoto 4y ago> Or OS authors are going to have to rethink how they handle illegal instruction exceptions, by patching the calling program to call into an emulated version when running on hardware that lacks support; […] 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.
- hajile 4y agoThe foundation releases profiles. 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.adoc https://github.com/riscv/riscv-profiles/blob/main/profiles.a...
- hajile 4y agoThere are only 2 major versions of RISC-V for desktop processors (64-bit with privileged mode) with a third likely coming in 2023 or 2024. That's definitely better than the competition. 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.
- sparkie 4y agoThere's far more than 2. 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/search?q=public%20review%20extension 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/existing_extensions/Huawei%20Custom%20Extension 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.
- Vt71fcAqt7 4y ago