cpu-architecturebitenergymicro-architecture

Does storing false bool values cost less electrical energy?


Going to sleep tonight I have been wondering: if bool, in C++ for example, is set to false that mean, that all of it’s (8 or 16)bits are set 0(seems to be).

Zero bit, as far as I know, means no current flowing in some transistor, so, hence false bool will waste energy in some device with battery less than true?

So if yes, it will be better to, for example, in functions set defaults boolean (or even maybe other) parameters as false:

Instead of:

void DrawImage(int x, int y, bool cached = true);

Do

void DrawImage(int x, int y, bool not_cached = false);

Solution

  • Zero bit, as far as I know, means no current flowing in some transistor, so, hence false bool will waste energy in some device with battery less than true?

    No, not for that reason. CMOS logic has no current flowing in either static state, only in the transition between states (to charge / discharge the parasitic capacitance, and any shoot-through current that flows as the pull-up and pull-down transistors both partially conduct for a moment). Apart from leakage current, of course, which is somewhat significant at lower clock speeds.

    CMOS is more or less symmetric, except for differences between N-channel and P-channel MOSFETs, so 1 isn't different from 0 in terms of voltage states and how transistors let charge flow.

    You'd be right for the output of one gate in some other logic families like TTL (bipolar transistors with pull-up resistors), where a transistor would pull current to ground through a pull-up resistor or not. But only for one gate; usually logic involves multiple inversions, because an amplifier naturally inverts (in CMOS or TTL or RTL).

    Also only for 1 bit out of 64 in the register used for arg-passing. The CPU's pipeline state, and the out-of-order execution machinery, take vastly more transistors (and gates) than just the actual architectural state (register values) and data being operated on. So the state of 1 bit is pretty negligible.

    The large number of tiny transistors in a CPU is why CPUs have used CMOS logic for decades, otherwise those static currents through pull-up resistors in RTL or TTL would melt them.

    Even with CMOS, power density has been a problem since the early 2000s (the "power wall" for frequency scaling, as described in Modern Microprocessors A 90-Minute Guide! which is pretty essential reading if you want to know more about CPU design considerations). In CMOS, it takes higher voltages to switch faster (about linearly), and the energy in a capacitor scales with V^2. And current only flows in CMOS when a gate switches from 0 to 1 or vice versa, and the rate of that happening is some factor of the CPU clock. So running at the minimum voltage for a given frequency, power scales with about f^3.


    Other factors that could make creating a 0 cheaper

    On x86, xor edi, edi is a cheaper instruction than mov edi, 1. On Sandybridge-family CPUs, it doesn't even need an execution unit in the back-end, so that's definitely some transistors that didn't need to be switching. As well as a smaller instruction (2 bytes vs. 5, or 3 for mov dil, 3 to save code size at the cost of partial-register performance penalties). So passing a 0 can perhaps improve performance, letting the same number of instructions finish sooner, letting the CPU get back to sleep sooner (race to sleep). Or not, there might easily be no effect, or different code alignment of later instructions might happen to be better with the longer instruction.

    Most other ISAs don't have as much different between zeroing vs. setting 1 in a register. And even on x86, this is not generally a very valuable optimization.

    But still, if you have a choice for one value to be special, 0 is a good choice, especially for non-bool integers since it's slightly more efficient to test for 0 vs. non-0 than for any other number. (So for example if you're using plain int, x != 0 is cheaper than x == 1. With a bool, a compiler can already just test for non-zero if you do b == true.)