Comment by tsimionescu
1 year ago
> hardware always "executes both sides" of a branch at once
Unless you're talking about quantum hardware, that is very much not true. The whole point of transistors is to choose whether to power one part of a circuit or another.
Plus, even for hardware, the solution to all this is to modularize all the way down. One piece of hardware sets up the right state and powers up another piece of hardware - this type of logic doesn't stop at the OS level. For drawing on the screen, ultimately you reach a piece of hardware that lights up in one of three colors based on that state - but all the way there, it's the same kind of "function calls" (and even more indirection, such as communication protocols) on many levels.
At least in CMOS, the power supplied to the transistor is not being modulated as part of logic operations. Modern hardware does clock gating and power gating of modules for power saving, but that is not what the OP is talking about.
In hardware the equivalent of a ternary is a mux, which can be made from a lot of parallel instances of
Or in other words, both branches must be computed and the correct value is chosen based on the condition.
"Power" was very sloppy language on my side. I was talking about the low voltage / high voltage difference that you get from transistors. A logical gate ultimately has a single output voltage based on its inputs. If its inputs are 1 and 1 (+5V and +5V), its output will be, say, 0 (0V), not "initially both 0 and 1, but later only 1 is chosen".
Similarly, a two bit adder is not going to have all 4 possible states internally or for some time - as soon as the input voltage is applied to its inputs, its output voltages will correspond to the single result (disregarding the analog signal propagation, which I assume is not what you were talking about).
Similarly, a conditional jump instruction will not be implented natively by computing both "branches". It will do a single computation to set the instruction pointer to the correct value (either current + 1 or destination). Now sure, speculative execution is a different matter, but that is extra hardware that was added late in the processor design process.
You can’t really conditionally compute something in hardware. The hard to do the computation exists and is wired up always.
The conditional jump is a great example actually. Typically this would be implemented by having one block compute PC+<instruction size> and another block compute the jump target and then choosing between the two using a mux
2 replies →
At least for classic textbook CPUs, it's common to run both sides of a decision in parallel while it's still being made, then finally use a transistor to select the desired result after the fact. No one wants the latency of powering everything up and down every cycle, except on the largest scales where power consumption makes a big difference.
I don't understand what you mean by decision. In a textbook CPU, where there is no speculative execution and no pipelining, the hardware runs one instruction at a time, the one from the instruction pointer. If that instruction is a conditional jump, this is a single computation that sets the instruction pointer to a single value (either next instruction or the specified jump point). After the single new value of the instruction pointer is computed, the process begins again - it fetches one instruction from the memory address it finds in the instruction point register, decodes it, and executes it.
Even if you add pipelining, the basic textbook design will stall the pipeline when it encounters a conditional/computed jump instruction. Even if you add basic speculative execution, you still don't get both branches executed at once, necessarily - assuming you had a single ALU, you'd still get only one branch executed at once, and if the wrong one was predicted, you'll revert and execute the other one once the conditional finishes being computed.
> I don't understand what you mean by decision.
I'm talking on a lower level than the clock cycle or instruction. Let's say circuit A takes X and outputs foo(X), and circuit B takes X and outputs bar(X). We want to build a circuit that computes baz(X, Y) = Y ? foo(X) : bar(X), where X is available before Y is. Instead of letting Y settle, powering up one of the circuits A or B, and sending X into it, we can instead send X to circuits A and B at the same time, then use Y to select whichever output we want.
1 reply →