7 ms·
The article is conflating three separate issues: (1) The amount of compute and/or data motion that can be achieved with a single instruction. This is really ab
by dgacmu 7y ago
The article is conflating three separate issues:
(1) The amount of compute and/or data motion that can be achieved with a single instruction. This is really about amortizing the cost of decode and allowing the pipeline to be kept full by producing a lot of work from a single instruction.
(2) efficiency gains from vector processing. This both amortizes the cost of decode and produces the amount of control circuitry relative to the number of ALUs --> more flops/area. it also generally favors larger sequential memory accesses which is good for bandwidth.
(3) extracting parallelism from the instruction stream. The VLIW debate is about whether that should be done by the CPU itself, e.g., in the form of out-of-order execution, or whether it should be handled by the compiler. VLIW allows the compiler to do this work, which keeps the CPU simpler.
It's been clear for several years that larger vectors are a win, and that's been happening in the Intel and arm space, not to mention GPU. The VLIW debate is less clear, and has been going back and forth. I think that we have been doing a better job of getting a handle on when instruction complexity and diversity is beneficial versus not - remember that the initial RISC proposal was in contrast to the PDP instruction set, which was kind of ridiculously over specialized for the technology of the time.
- simias 7y ago>remember that the initial RISC proposal was in contrast to the PDP instruction set, which was kind of ridiculously over specialized for the technology of the time. That's a good point and I expect that it still somewhat holds true today: many of the RISC supporters (and I'm one of them) effectively assimilate CISC with x86 since that's by far the most popular CISC instruction set out there these days[1]. And x86 is the C++ of instruction sets: decades and decades of legacy feature which shouldn't be used in modern code, a large selection of paradigms copied from whatever other instruction set was popular at the time. You want to do BCD? We have opcodes for that (admittedly no longer supported in long mode, but it's there). Also do you like prefixes? Asking for a friend. But obviously that's a bit of a fallacy, one could design a modern CISC-y IA without all the legacy baggage of x86. It's not so much that I love MIPS or RISC V, it's that I don't want to have to deal with x86 anymore. [1] We don't yet consider ARM CISC, right?
- Taniwha 7y agoActually it was in contrast to the Vax instruction set ... the PDP instruction set is something else (and some Vax's had a PDP emulation mode ....)
- monocasa 7y agoVAX was a crazy town ISA too, with stuff like single isntruction polynomial evaluation.
- dragontamer 7y agoCrazy for its age, but all modern processors (x86, ARM, and Power9) implement a polynomial multiplication. ARM: vmull.p8 Intel: PCLMULQDQ Power9: I forget, but trust me, its in there somewhere. IIRC, they're all 64-bit carryless (or polynomial) multiplications. The funniest part is that ARM and Power9 still claim to be "reduced instruction set computers", despite having highly specialized instructions like these. Power9 is the funniest: implementing hardware-level decimal-floats (for those bankers running COBOL), quad-floats (for the scientific community), Polynomial-Multiplication and more.
- floatboth 7y agoWell, the meaning of "reduced" has shifted from "not having specialized instructions" to "load-store and preferably fixed-length". Here's a CRC32 impl using POWER8/9 polynomial instructions: https://github.com/antonblanchard/crc32-vpmsum https://github.com/antonblanchard/crc32-vpmsum — coincidentally, you don't have to do this on ARM, ARM just has CRC32 instructions. > hardware-level decimal-floats (for those bankers running COBOL) IBM being IBM :) I've heard somewhere that they are sharing some internals between POWER and z/Architecture (mainframe) chips. No idea how true it is and how much is shared if true, but a scenario like "decimal floats were implemented because mainframes are using the same backend with a different frontend, so we exposed them in the POWER frontend too" sounds quite plausible.
- 7y ago
- cptskippy 7y ago> The amount of compute and/or data motion that can be achieved with a single instruction. This is really about amortizing the cost of decode and allowing the pipeline to be kept full by producing a lot of work from a single instruction. I'm basing this on my knowledge from CS classes in the late 90s but isn't the point of RISC for the decode to be very simple because the instructions are very simple? Much of the optimization of x86 has been in the Decode where a CISC can be transformed in to multiple and often parallel instructions. And parallelism where we've seen our gains and benefited the most in the last ~10-15 years of CPU design. Does that mean in order for RISC to be performant some degree of parallelism will have to be done by the compiler? Isn't that what ultimately killed Itanium which was a VLIW processor?
- seanmcdirmid 7y agoYes, even if VLIW failed, GPUs are showing us that there is a lot of performance to be had in switching from hardware to software scheduled parallel memory accesses.
- dragontamer 7y agoGPUs advantage isn't from scheduling IMO. You are correct in that GPUs have a degree of software scheduled memory instructions. There's no Out-of-order schedulers in AMD or NVidia. The best you got is "start memory load/store", and "synchronize" kind of instructions. On AMD, you perform s_waitcnt to wait for memory to respond. NVidia has read/write barriers + stall counts encoded into each instruction that performs a similar task. However, I argue that GPU advantage comes from the innate "warp" / "wavefront" model. The programmer will specify 100,000+ "SIMD threads" of execution. There are blatantly obvious ways to optimize the memory access when you have hundreds-of-thousands of threads stepping together. In particular: with 32-threads operating at a time, you can stripe the data so that the 32-threads all access 128-byte chunks at a time. (Thread-local variable "uint32_t foo" for threads #0 through #31 can be stored in memory location #0 through #127. When threads #0 through #31 read "foo" they only need to perform 2-memory transfers: because modern memory reads/writes 64-byte blocks at a time). "Striping" memory access, and grouping memory accesses together (aka coalescing) is very important for modern GPU (and CPU) memory optimization. Its far easier to do on GPUs due to the parallel model. In fact, all thread-local variables are optimized as such in GPU-code, its basically automatic. CPUs attempt to do the same through auto-prefetching. But it doesn't get as far as the GPU-approach. GPUs benefit from wide memory busses, because of the wavefront / warp model of programming. 32+ threads grab memory, and stall on memory, at the same time. Its more efficient to calculate memory stalls for the 32+ batch of threads (one warp) rather than doing it one-at-a-time like a CPU.
- gandalfgeek 7y agoIndeed. If you look at Patterson's initial paper that makes the argument for RISC, he compares it to the VAX instruction set that had support for managing doubly-linked lists, polynomial evaluation, string matching and CRC among other things! Did a little explainer video on that: https://youtu.be/o14ecAoGN8w?t=105 https://youtu.be/o14ecAoGN8w?t=105