Live data from Hacker News

XOR'ing a register with itself is the idiom for zeroing it out. Why not sub?

devblogs.microsoft.com

151–160 of 231 posts

Re: XOR'ing a register with itself is the idiom for zeroing it out. Why not sub?

#151

XOR is a simple logic-gate operation. SUB would have to be an ALU operation. A one-bit adder (which is subtraction in reverse) makes signals pass through two gates. See https://en.wikipedia.org/wiki/Adder_(electronics) You need the 2 gates for adding/subtracting because you care about carry. So if you're adding/subtracting 8 bits, 16 bits, or more, you're connecting multiples of these together, and that carry has to…

It's still the same number of clock cycles, though, isn't it? You're using some extra circuitry during the SUB, but during the XOR, that circuitry is just sitting idle anyway, so it's still six of one/half a dozen of the other.

It all depends on the CPU architecture, if it supports something like out-of-order execution then both parts of the CPU could be in use at the same time to execute different instructions. Realistically any CPU with that level of complexity doesn't care about SUB vs XOR though.

Re: XOR'ing a register with itself is the idiom for zeroing it out. Why not sub?

#152
post #78

On some of IBM's smaller processors, such as channel controllers and the CSP used in the midrange line prior to the System/38, the xor instruction had a special feature when used with identical source and destination - It would inhibit parity and/or ECC error checking on the read cycle, which meant that xor could be used to clear a register or memory location that had been stored with bad parity without taking a mach…

Interesting, since the general culture at IBM seems to have preferred SUB over XOR -- their earlier business-oriented machines didn't even have a XOR instruction, and even on later ones the use of SUB has persisted, including in the IBM PC and AT BIOS. (There was another, now deleted, comment somewhere in this thread that mentioned IBM's preference for SUB. Source of that statement was Claude, but it seems very likel…

You may not be looking for the right thing. On the aforementioned CSP, the instruction that performed XOR was called "XR" and not "XOR". My source is firsthand knowledge; I was a CE and performed service calls on the System/34, System/36, 370, and 390.

In any case, I am describing equipment built mostly in late 60s through the late 70s at IBM Rochester and Poughkeepsie. The IBM PC was developed by an entirely different team at IBM Boca Raton, and IBM didn't design its CPU.

Re: XOR'ing a register with itself is the idiom for zeroing it out. Why not sub?

#153
post #78

On some of IBM's smaller processors, such as channel controllers and the CSP used in the midrange line prior to the System/38, the xor instruction had a special feature when used with identical source and destination - It would inhibit parity and/or ECC error checking on the read cycle, which meant that xor could be used to clear a register or memory location that had been stored with bad parity without taking a mach…

Interesting, since the general culture at IBM seems to have preferred SUB over XOR -- their earlier business-oriented machines didn't even have a XOR instruction, and even on later ones the use of SUB has persisted, including in the IBM PC and AT BIOS. (There was another, now deleted, comment somewhere in this thread that mentioned IBM's preference for SUB. Source of that statement was Claude, but it seems very likel…

Another thing I should point out is that the CSP instruction set was not documented to the customer. The CSP software was called "Microcode" and the customer was not told about the CSP's design or how it worked. The documented instruction set for the System/34 and System/36 is that of the Main Storage Processor or MSP, which was an evolution of the IBM System/3.

Re: XOR'ing a register with itself is the idiom for zeroing it out. Why not sub?

#154

Earlier quoted context omitted.

Nope. In any ALU the speed is determined by the slowest operation, so XOR is never faster. It does not matter which is the width of the ALU, all that matters is that an ALU does many kinds of operations, including XOR and subtraction, where the operation done by an ALU is selected by some control bits. I have explained in another comment that the only CPUs where XOR can be faster than subtraction are the so-called su…

> In any ALU the speed is determined by the slowest operation, so XOR is never faster. On a 386, a reg/reg ADD is 2 cycles. An r32 IMUL is "9-38" cycles. If what you stated were true, you'd be locking XOR's speed to that of DIV. (Or you do not consider MUL/DIV "arithmetic", or something.) https://www2.math.uni-wuppertal.de/~fpf/Uebungen/GdR-SS02/op... > I have explained in another comment that the only CPUs where XOR…

> Or you do not consider MUL/DIV "arithmetic", or something.

Multiplier and divider are usually not considered part of the ALU, yes. Not uncommon for those to be shared between execution threads while there's an ALU for each.

Re: XOR'ing a register with itself is the idiom for zeroing it out. Why not sub?

#155
post #27

Earlier quoted context omitted.

Quite a few architectures have a dedicated 0 register.

Indeed!! MIPS - $zero RISC-V - x0 SPARC - %g0 ARM64 - XZR

On 64-bit ARM, the same register number is XZR in some instructions and the stack pointer in others.

Re: XOR'ing a register with itself is the idiom for zeroing it out. Why not sub?

#156
post #144

SUB has higher latency than XOR on some Intel CPUs: latency (L) and throughput (T) measurements from the InstLatx64 project ( https://github.com/InstLatx64/InstLatx64 ) : | GenuineIntel | ArrowLake_08_LC | SUB r64, r64 | L: 0.26ns= 1.00c | T: 0.03ns= 0.135c | | GenuineIntel | ArrowLake_08_LC | XOR r64, r64 | L: 0.03ns= 0.13c | T: 0.03ns= 0.133c | | GenuineIntel | GoldmontPlus | SUB r64, r64 | L: 0.67ns= 1.0 c | T: 0.…

[deleted]

Re: XOR'ing a register with itself is the idiom for zeroing it out. Why not sub?

#157

I vaguely remember we used the XOR trick on processors other than Intel, so it may not be Intel-specific. In principle, sub requires 4 steps: 1. Move both operands to the ALU 2. Invert second operand (twos complement convert) 3. Add (which internally is just XOR plus carry propagate) 4. Move result to proper result register. This is absolutely not how modern processors do it in practice; there are many shortcuts, but…

These two steps usually run in parallel though, with transistors to enable them depending on what operation should be performed.

Re: XOR'ing a register with itself is the idiom for zeroing it out. Why not sub?

#158
I recall thinking about these things quite a bit when reading Michael Abrash back in the 90s.

How much of that advice applies to anything these days is questionable. Back then we used to squeeze as much as possible from every clock cycle.

And cache misses weren’t great but the “front side bus” vs CPU clock difference wasn’t so insane either. RAM is “far away” now.

So the stuff you optimize for has changed a bit.

Always measure!

Re: XOR'ing a register with itself is the idiom for zeroing it out. Why not sub?

#159

XOR is a simple logic-gate operation. SUB would have to be an ALU operation. A one-bit adder (which is subtraction in reverse) makes signals pass through two gates. See https://en.wikipedia.org/wiki/Adder_(electronics) You need the 2 gates for adding/subtracting because you care about carry. So if you're adding/subtracting 8 bits, 16 bits, or more, you're connecting multiples of these together, and that carry has to…

That's all true, but on any modern x86 processor both the single pair of gates for the xor and the 10 or so for a carry-bypass 64 bit wide subtraction both happen with a single clock cycle of latency so from a programmer's perspective they're the same in that sense. There's still an energy difference but its tiny compared to what even the register file and bypass network for the operation use, let along the OoO struc…

The blog post is about why this is idiomatic not whether it needs to be done that way today. It’s idiomatic because once upon a time none of that existed and xor gates did. The author apparently never took intro to digital logic.

Re: XOR'ing a register with itself is the idiom for zeroing it out. Why not sub?

#160

Earlier quoted context omitted.

Interesting, since the general culture at IBM seems to have preferred SUB over XOR -- their earlier business-oriented machines didn't even have a XOR instruction, and even on later ones the use of SUB has persisted, including in the IBM PC and AT BIOS. (There was another, now deleted, comment somewhere in this thread that mentioned IBM's preference for SUB. Source of that statement was Claude, but it seems very likel…

You may not be looking for the right thing. On the aforementioned CSP, the instruction that performed XOR was called "XR" and not "XOR". My source is firsthand knowledge; I was a CE and performed service calls on the System/34, System/36, 370, and 390. In any case, I am describing equipment built mostly in late 60s through the late 70s at IBM Rochester and Poughkeepsie. The IBM PC was developed by an entirely differe…

I don't doubt that this specific processor special-cased XOR (regardless of how it was called in the assembly language)!

Merely pointing out that where both operations were available, there seems to have been a preference to use SUB instead, with some continuity from early business-oriented mainframes, to the 360, to the PC.

Post reply on HN