我在一篇博客文章中读到,最近的 X86 微架构也能够在寄存器重命名器中处理常见的寄存器归零习惯用法(例如与自身异或寄存器);用作者的话来说:
“寄存器重命名器也知道如何执行这些指令——它可以将寄存器本身归零。”
有人知道这在实践中是如何工作的吗?我知道一些 ISA,如 MIPS,包含一个在硬件中始终设置为零的架构寄存器。这是否意味着在内部,X86 微体系结构在内部具有类似的“零”寄存器,这些寄存器在方便时映射到?或者我的心智模型对这些东西在微架构上的工作方式不太正确?
我问的原因是因为(从某些观察)看来mov
,在一个循环中从一个包含零的寄存器到一个目的地,仍然比在循环内通过 xor 将寄存器归零快得多。
基本上发生的事情是我想根据条件将循环内的寄存器归零;这可以通过提前分配一个架构寄存器来存储零(%xmm3
在这种情况下),在整个循环期间不会修改,并在其中执行以下操作来完成:
movapd %xmm3, %xmm0
或者使用 xor 技巧:
xorpd %xmm0, %xmm0
(两种 AT&T 语法)。
换句话说,选择是在循环之外提升一个常量零还是在每次迭代中重新实现它。后者将实时架构寄存器的数量减少了一个,并且,由于处理器对异或习语的假定特殊情况感知和处理,它似乎应该与前者一样快(特别是因为这些机器有更多的物理无论如何,寄存器都比架构寄存器要好,因此它应该能够在内部执行与我在程序集中所做的等效的操作,方法是在内部提升常量零甚至更好,同时完全了解和控制自己的资源)。但似乎并非如此,所以我很好奇是否有任何具有 CPU 架构知识的人可以解释是否有一个很好的理论理由。
本例中的寄存器恰好是 SSE 寄存器,而机器恰好是 Ivy Bridge;我不确定这两个因素的重要性。