4 ms·
CSINC and even CMOVBL do not sound "fairly simple". Maybe it is because the mental model of higher level programmer - for an application programmer, anything t
by thriftwy 3y ago
CSINC and even CMOVBL do not sound "fairly simple".
Maybe it is because the mental model of higher level programmer - for an application programmer, anything that involves writing and reading main memory directly is considered simple, whereas combining a conditional, an increment and a write in a single op sounds "not simple".
- Arnt 3y agoModern CPUs often keep a hundred instructions in flight, and accessing main memory once can take more time than a hundred simple instructions. Accessing main memory involves cache coherency protocol logic with neighbouring cores, and it may involve locking if the program wants a read barrier, a write barrier or any kind of volatile variable. Instructions like CMOVBL involve only a small number of CPU registers, nothing else, and can't interact with instructions far ahead or behind them in the instruction stream, or with other cores/threads at all. Very little state. They're simple to reason about, both for the compiler authors, the CPU and the poor developer who's chasing a threading bug.
- flohofwoe 3y agoFWIW, the original ARM CPU from 1985 (which was a very 'pure' RISC implementation) already could execute each instruction conditionally, the condition bit mask was just part of the regular opcode structure: https://en.wikichip.org/wiki/arm/armv1 https://en.wikichip.org/wiki/arm/armv1
- thequux 3y agoKeep in mind that when the CISC vs RISC distinction was coined, the predominant architectures were things like IBM System/370 and VAX. System/370 has an instruction that inserts an item into a heap. (and modern Z/Architecture is worse: there are instructions like "compute the HMAC of this data" where the MAC algorithm is in a register.) VAX had an instruction that computed the roots of a polynomial. The world is very different now. RISC won, and it won hard. x86 got a lot more registers, and most of the baroque instructions are no longer used because they got relegated to microcode. As it's used, it's much closer to Berkeley RISC than it is to VAX or S/370. ARM is even more so: the only instructions that touch memory are loads and stores. As a rough approximation, "simple" instructions can be implemented in a reasonable amount of silicon without microcode, and complex instructions can't.
- klelatti 3y agoWell all modern architectures have FP and SIMD so it’s not as though complex (microcoded) instructions have been banished.
- atq2119 3y agoSIMD instructions are generally not microcoded though because they are not actually complex. A SIMD addition has pretty much the same microarchitectural complexity as a scalar addition. If you're looking for truly complex instructions, you should look for things like VMENTER or IRET.
- stephencanon 3y agoMost SIMD and FP instructions are not microcoded in a modern mainstream CPU, FWIW.
- klelatti 3y agoInteresting. I sort of expected that for basic FP / SIMD but not for the full range - eg trig functions. Is that wrong?
- stephencanon 3y agoThere really aren't complex math functions in most SIMD ISAs(1), these functions are implemented in software instead. Even for scalar operations, no one(2) uses the x87 trig functions either, as software implementations are both faster and more accurate and have been for a couple decades. (1) various HPC folks have proposed and used extensions that do _part_ of a complex math operation in SIMD at various times, and on GPUs this sort of thing is very common. (2) except for math libraries that haven't been updated for a couple decades.
- deleted 3y ago[deleted]
- 3y ago
- throwawaylinux 3y agoIt's not a write, it's just a destination register. There isn't supposed to be some absolute number of instructions that a RISC has, the idea behind it is that you would take a quantitative approach to add instructions, and require that they show benefit beyond a composition of other instructions, and could be practically used. More capable compilers, wider use of vectorization and other techniques, and more transistors has pushed that a long way since the 1980s.
- Symmetry 3y agoIt really is very simple from a hardware standpoint. You have a little box in the execution unit with two regular inputs and one single bit input and one regular output. Once you have adds with carry you already have to have that structure of inputs in place, which has implications throughout your scheduler, but adding CSINC at that point is almost trivial. Complicated things migth be something like division, which can take multiple cycles during which that functional block is busy, or a floating point addition where there are all sorts of complicated rules involving implicit global state around rounding and subnormal and NaNs. Or, most terrifying of all, a load which might target a memory that's been paged out and so require you to bring all the scores of instructions in flight to a halt, switch over to OS code, page in the memory, and then resume as if that one load instruction was the only thing executing at the time the exception happened.
- msla 3y agoIt's simple, in part, because it only operates on registers and immediate values, so there's no chance of it taking a page fault. That makes it easy to pipeline, and, compared to having to save a lot of ALU state after a fault, the operation this opcode performs is, indeed, fairly simple.