【问题标题】:How does a zero register improve performance?零寄存器如何提高性能?
【发布时间】:2014-08-30 00:45:23
【问题描述】:

在 MIPS ISA 中,有一个零寄存器 ($r0),它总是给出零值。这允许处理器:

  1. 任何产生要丢弃的结果的指令都可以将其目标指向该寄存器
  2. 成为0的来源

source 中说这提高了 CPU 的速度。它如何提高性能?不是所有的ISA都采用这个零寄存器的原因是什么?

$r0 不是通用的。它被硬连线为 0。不管你是什么 做这个寄存器,它的值总是0。你可能想知道为什么 MIPS 中需要这样的寄存器。

MIPS 的设计者使用基准测试(用于确定 CPU 的性能),这使他们确信拥有一个寄存器 硬连线为 0 将提高 CPU 的性能(速度),因为 反对没有它。不是每个人都同意一个硬连线的寄存器 0 是必不可少的,因此并非所有 ISA 都有零寄存器。

【问题讨论】:

标签: mips cpu-registers instruction-set


【解决方案1】:

这有几种可能的方法可以提高性能;目前尚不清楚哪些适用于该特定处理器,但我已大致按照从最可能到最不可能的顺序列出了它们。

  1. 它避免了虚假的流水线停顿。如果没有显式的零寄存器,则需要获取一个寄存器,将其清零并使用它的值。这意味着使用归零操作取决于归零操作,并且(取决于流水线转发系统的强大程度)可能取决于归零寄存器的先前值。像 x86 这样的架构具有非常小的寄存器文件,并且基本上将它们的寄存器虚拟化以防止导致问题,它们具有非常强大的危害分析工具。 RISC 处理器通常并非如此。
  2. 如果某些操作可以避免寄存器读取,则它们可能更易于流水线化。如果使用显式零寄存器,则操作数为零的事实在指令解码阶段是已知的,而不是稍后在寄存器获取阶段。因此,可以跳过寄存器读取阶段。
  3. 同样,显式丢弃结果的能力避免了寄存器写入阶段的需要。
  4. 当已知操作数之一为零或已知结果被丢弃时,某些操作可能会生成更简单的微码。
  5. 显式零寄存器减轻了编译器优化器的压力,因为它不需要对其寄存器分配非常小心(无需识别不会导致读取或写入停止的寄存器)。

【讨论】:

  • 在更简单的 CPU 上,如果 ISA 需要更少的操作码,则解码会带来好处。拥有一个零寄存器意味着 mov-immediate 注册可以是ori dst, $zero, 1234 的别名,而不需要它自己的操作码。在带有 FLAGS 的 ISA(与 MIPS 不同)上,cmp 可以是 sub,以 $zero 作为目标。
【解决方案2】:

对于您的每件商品,这里有一个答案。

  1. 考虑强制使用寄存器进行输出的指令,您希望在该寄存器中丢弃此输出。通常,您必须确保有可用的空闲寄存器,如果没有,请将您当前的一些寄存器压入堆栈,这是一项昂贵的操作。显然,操作的输出被丢弃的情况经常发生,处理这种情况的最简单方法是提供一个“未使用”的寄存器。
  2. 既然我们有这样一个未使用的寄存器,为什么不使用它呢?您想将某些东西零初始化或将某些东西与零进行比较的情况经常发生。漫长的方法是首先将零写入该寄存器(这需要额外的指令机器代码中零的文字,其形式可能是0x00000000,相当长)然后用它。因此,减少了一条指令,并减少了您的程序大小。

这些优化可能看起来有点微不足道,并且可能会引发一个问题:“这实际上改善了多少?”这里的答案是,上面描述的操作显然在你的 MIPS 处理器上使用了很多。

【讨论】:

  • 丢弃指令的输出在 x86 上很有用,其中指令具有设置条件代码等副作用。 MIPS 指令只有一个输出,因为这是一种 RISC 架构,很少需要丢弃指令的输出。
【解决方案3】:

零寄存器的概念并不新鲜。我第一次在 CDC 6600 大型机上遇到它,可以追溯到 1960 年代中后期。在某些方面,它是最早的 RISC 处理器之一,并且是 5 年来世界上最快的计算机。在该架构中,“B0”寄存器被硬连线为始终为零。 http://en.wikipedia.org/wiki/CDC_6600

这种寄存器的好处主要是它简化了指令集。当简单和常规指令集的解码和编排可以在没有微代码的情况下实现时,它会提高性能。此外,对于 6600 与当今大多数 LSI 芯片一样,信号通过“导线”长度所花费的时间成为执行速度的关键因素,并且保持指令集简单(并避免微代码)允许更少的晶体管,并导致更短的电路路径。

【讨论】:

    【解决方案4】:

    零寄存器允许在设计一个新的 指令集架构 (ISA)。

    例如,main RISC-V spec 有 32 个伪指令 取决于零寄存器(参见表 26.2 和 26.3)。伪指令是 由汇编器映射到另一个实数的指令 指令(例如,分支如果等于零被映射到 分支如果相等)。为了比较:主要的 RISV-V 规范列出了 164 真正的指令操作码(即计算 RV(32|64)[IMAFD] 基础/扩展,又名 RV64G)。这意味着如果没有零寄存器 RISC-V RV64G 会为这些指令多占用 32 个操作码(即多 20%)。对于具体的 RISC-V CPU 实现时,这种实伪指令比率可能会向任一方向移动 取决于选择了哪些扩展。

    使用较少的操作码可以简化指令解码器。

    更复杂的解码器需要更多时间来解码指令 或占用更多门(不能用于更有用的 CPU 单元) 或两者兼而有之。

    现有的、逐步开发的 ISA 必须应对 向后兼容。因此,如果您的原始 ISA 设计 不包括零寄存器,你不能只是在以后添加它 在不破坏兼容性的情况下进行修订。此外,如果您现有的 ISA 已经需要一个非常复杂的解码器,然后添加一个零 注册没有回报。

    除了现代 RISC-V ISA(自 2010 年开发,第一个 2019 年批准)、ARMv8 AArch64(2011 年发布的 64 位 ISA)、 与之前的 ARM 32 位 ISA 相比,它还具有零寄存器。因为这个和其他的变化 AArch64 ISA 与之前的 ARM 32 位的共同点要少得多 ISA 比 - 比如说 - x86 和 x86-64 ISA。

    相对于 AArch64,x86-64 没有零寄存器。虽然 x86-64 比 以前的 32 位 x86 ISA,它的 ISA 只是增量更改。 因此,它具有所有现有的 x86 操作码以及 64 位 变体,因此解码器已经非常复杂。

    【讨论】:

      猜你喜欢
      • 2013-08-01
      • 1970-01-01
      • 2016-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-18
      • 1970-01-01
      相关资源
      最近更新 更多