<story><title>The surprising subtleties of zeroing a register (2012)</title><url>https://randomascii.wordpress.com/2012/12/29/the-surprising-subtleties-of-zeroing-a-register/</url></story><parent_chain><item><author>philh</author><text>Author in the old thread (&lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;news.ycombinator.com&amp;#x2F;item?id=19262249&quot; rel=&quot;nofollow&quot;&gt;https:&amp;#x2F;&amp;#x2F;news.ycombinator.com&amp;#x2F;item?id=19262249&lt;/a&gt;) says&lt;p&gt;&amp;gt; An x86-64 CPU has sixteen integer registers, but 100-200 physical integer registers. Every time an instruction writes to, say, RAX the renamer chooses an available physical register and does the write to it, recording the fact that RAX is now physical-register #137. This allows the breaking of dependency chains, thus allowing execution parallelism.&lt;p&gt;I&amp;#x27;m curious why they have so many more physical registers than... logical? registers. I have a couple of guesses:&lt;p&gt;* Physical registers are physically cheaper to add than logical registers.&lt;p&gt;* Adding logical registers breaks backwards compatibility, or at best means you get no speedup on things written (&amp;#x2F;compiled) for fewer logical registers. Adding physical registers lets you improve performance without recompiling.&lt;p&gt;* Adding logical registers increases complexity for people writing assembly and&amp;#x2F;or compilers. Adding physical registers moves that complexity to people designing CPUs.&lt;p&gt;Are some of these correct? Other reasons I&amp;#x27;m missing?</text></item></parent_chain><comment><author>ridiculous_fish</author><text>Don&amp;#x27;t think of %eax as a real register. Think of it as a tag in a compressed dataflow graph. The compression is performed by the compiler&amp;#x27;s register allocator, and the decompression is performed by the CPU&amp;#x27;s register renaming.&lt;p&gt;A compiler&amp;#x27;s IR is a directed graph, where nodes are instructions and tagged by an assigned register. It would be pleasant to assign each node a distinct register, but then machine instructions would be unacceptably large. So the compiler&amp;#x27;s register allocator compresses the graph, by finding nodes that do not interfere and assigning them the same register.&lt;p&gt;The CPU&amp;#x27;s register renamer then reinflates this graph, by inspecting the dataflow between instructions. If two instructions share a register tag, but the second instruction has no dependence on the first, then they may be assigned different physical registers.&lt;p&gt;`xor eax, eax` has no dependence on any instruction, so it can be specially recognized as allocating a new physical register. In this way of thinking, `xor eax, eax` doesn&amp;#x27;t zero anything, but is like malloc: it produces a fresh place to read&amp;#x2F;write, that doesn&amp;#x27;t alias anything else.</text></comment>
<story><title>The surprising subtleties of zeroing a register (2012)</title><url>https://randomascii.wordpress.com/2012/12/29/the-surprising-subtleties-of-zeroing-a-register/</url></story><parent_chain><item><author>philh</author><text>Author in the old thread (&lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;news.ycombinator.com&amp;#x2F;item?id=19262249&quot; rel=&quot;nofollow&quot;&gt;https:&amp;#x2F;&amp;#x2F;news.ycombinator.com&amp;#x2F;item?id=19262249&lt;/a&gt;) says&lt;p&gt;&amp;gt; An x86-64 CPU has sixteen integer registers, but 100-200 physical integer registers. Every time an instruction writes to, say, RAX the renamer chooses an available physical register and does the write to it, recording the fact that RAX is now physical-register #137. This allows the breaking of dependency chains, thus allowing execution parallelism.&lt;p&gt;I&amp;#x27;m curious why they have so many more physical registers than... logical? registers. I have a couple of guesses:&lt;p&gt;* Physical registers are physically cheaper to add than logical registers.&lt;p&gt;* Adding logical registers breaks backwards compatibility, or at best means you get no speedup on things written (&amp;#x2F;compiled) for fewer logical registers. Adding physical registers lets you improve performance without recompiling.&lt;p&gt;* Adding logical registers increases complexity for people writing assembly and&amp;#x2F;or compilers. Adding physical registers moves that complexity to people designing CPUs.&lt;p&gt;Are some of these correct? Other reasons I&amp;#x27;m missing?</text></item></parent_chain><comment><author>brucedawson</author><text>Adding more logical registers is compatibility breaking. And, since you have to encode the register specifier in the instruction it means larger instructions (hence the compatibility breaking) which makes reading and decoding instructions slower.&lt;p&gt;And, regardless of how many logical registers you have you need to have more physical registers. These are needed for out-of-order (OOO) execution and speculative execution. An OOO super-scalar speculative CPU can have hundreds of instructions in flight and these instructions all need physical registers to work on. If you don&amp;#x27;t have excess physical registers you can&amp;#x27;t do OOO or speculative execution.</text></comment>