4 ms·
None of the CPUs compared have very reduced (as in few) number of instructions. We've come quite far from MIPS1, IBM 801 and the first SPARCs in terms of ISA co
by JoachimS 11y ago
None of the CPUs compared have very reduced (as in few) number of instructions. We've come quite far from MIPS1, IBM 801 and the first SPARCs in terms of ISA complexity.
The big difference is really that x86 has an ISA->uop decoder, which basically is another decoder in front of the decoder in a RISC.
- Symmetry 11y agoPretty much every deep OoO design is going to have uops inside. Look at the A15 here, for instance: http://regmedia.co.uk/2011/10/20/arm_a15_pipeline_large.jpg http://regmedia.co.uk/2011/10/20/arm_a15_pipeline_large.jpg On ARM most of your splitting is going to be breaking out the predication so that the scheduler only has to work with 2 input uops. The thing about x86 is that the instruction stream isn't self-synchronizing, it's hard and occasionally impossible to figure out where the instruction boundaries are if you don't decode progressively from the front. This means that to decode mulitple instructions per clock cycle x86 has to use complicated voodoo.
- cbd1984 11y agoRISC wasn't about reducing the number of instructions, it was about reducing the instructions themselves, to make them simpler and faster to execute.
- daemonwrangler 11y agoAlso simpler to decode. If you look at how much chip area goes to the frontend decoder in an x86 chip, that's a significant difference.
- Someone 11y agoI don't think simpler to decode necessitates fewer instructions. If all your instructions put the bits describing which registers to use in the same place, use the same way to specify constants instead of registers, to specify that they operate on floating point variables, etc, using 8 bits that select the instruction gives you 256 different discussion with limited added complexity. Of course, it is unlikely that you can make 256 instructions use the exact same format (some operations will not have any use for 3 registers, for instance) but if you can keep things as consistent as possible, decoding becomes easier. Price paid is that you sacrifice instruction space, for example because the instruction format allows you to write the result of an operation to a register hard-wired to contain a zero. And x86 isn't that CISC-y. There were processors that basically could do a simple number to string conversion in one instruction, and there _are_ processors with an instruction that does Unicode conversions (http://publibz.boulder.ibm.com/cgi-bin/bookmgr_OS390/BOOKS/dz9zr003/7.5.49 http://publibz.boulder.ibm.com/cgi-bin/bookmgr_OS390/BOOKS/d...)
- daemonwrangler 11y agoCan you use memory locations as operands in most instructions in the RISC ISAs these days? I always liked that RISC tended to have explicit Load and Store instructions to bring memory values into registers vs. being able to specify a register and a memory address as inputs to an instruction as you can in x86. Decoupling slow memory reads from the op that uses their values gives the CPU more flexibility in scheduling to try and hide the latency of memory ops.
- amyjess 11y agoRISC is ((reduced instruction) set computing), not (reduced (instruction set) computing). That is, the instructions are what's reduced, not the set. What makes an ISA RISC or CISC is how simple or complex each individual instruction is, not how many instructions are in the set. The point of RISC is that each instruction does one thing and only one thing. There's no addressing modes where a single instruction can access memory, perform some operation on the contents, and write it back into memory. This is why RISC is sometimes described as a strict load/store architecture.
- cbd1984 11y agoRISC is also often described as register-register, as opposed to register-memory or stack or accumulator-based. In a pure register-register design, all opcodes which use the ALU only operate on data stored in registers, and only store data to registers. Due to this, the only opcodes which touch RAM in such a design are load and store opcodes, and they only use the simplest addressing modes. In a register-memory design, ALU-using opcodes can touch RAM as well. This is taken to an extreme in accumulator-based designs, which aren't used much now but were previously very popular: One "main" register which is involved in all (or nearly all) opcodes, maybe a couple index registers to make memory addressing easier, and everything else is in RAM. The 6502 is the prototypical accumulator-based design, with the interesting twist that its zero page (all memory addresses with a high byte of 0x00) is almost as fast as registers, making it practically a machine with 256 one-byte registers. (Stack machines are fairly self-explanatory. I think they're mostly VMs now, because it's easy to take stack machine code, turn it back into a parse tree, and then compile that to optimized machine code.) Register-register designs are typically RISC, which implies constant-size opcodes (one machine word per) to save on decoding hardware, pipelining built in from the start (so no or few complicated opcodes which can take an unpredictable number of cycles to complete), and a very Spartan design philosophy, even to the extent of making the pipelining architecturally visible by specifying things like branch delay slots (where the opcode immediately after a taken branch opcode is still executed, because it's already in the pipeline). The idea was that the compiler would make it all invisible to the average programmer. The "no complex opcodes" thing was sometimes taken to extremes: There's no single-cycle algorithm for integer multiplication or division. MIPS therefore had integer multiplication and division opcodes which executed while the rest of the chip was still executing other opcodes: The code would issue a multiplication, say, and then the next n opcodes would be run while the multiplication hardware was cranking through the math; when it was done, the result would be placed in a pair of special registers, called hi and lo. How many opcodes was n? Dunno, it depended on the inputs to the multiplication opcode. Division worked the same way. I don't remember if reading hi and lo early would stall the pipeline or generate garbage... However, when you remember that the VAX had an opcode which would evaluate a polynomial of arbitrary degree when given an X value and a variable-length list of coefficients, you can kind of see where the RISC folk were coming from.