有几个因素导致寄存器比缓存快。
直接寻址与间接寻址
首先,寄存器是根据指令中的位直接寻址的。许多 ISA 将源寄存器地址编码在一个恒定位置,允许在指令解码之前将它们发送到寄存器文件,推测将使用一个或两个值。最常见的内存寻址模式通过寄存器间接寻址。由于基数+偏移寻址的频率,许多实现针对这种情况优化了流水线。 (在不同阶段访问缓存会增加复杂性。)缓存还使用标记并且通常使用集合关联性,这往往会增加访问延迟。不必处理未命中的可能性也降低了寄存器访问的复杂性。
复杂因素
乱序实现和具有堆叠或旋转寄存器的 ISA(例如,SPARC、Itanium、XTensa)会重命名寄存器。专用缓存,例如 Todd Austin 的背包缓存(直接使用偏移量索引缓存)和一些堆栈缓存设计(例如,使用小的堆栈帧号并使用该帧号和偏移量直接索引专用堆栈缓存的块)避免寄存器读取和添加。签名缓存将寄存器名称和偏移量与一小块存储相关联,从而为访问结构的较低成员提供较低的延迟。索引预测(例如,异或偏移和基数,避免进位传播延迟)可以减少延迟(以处理错误预测为代价)。人们也可以更早地为寄存器间接等更简单的寻址模式提供内存地址,但在两个不同的流水线阶段访问缓存会增加复杂性。 (Itanium 仅提供寄存器间接寻址 - 带有选项后增量。)方式预测(以及在直接映射缓存的情况下命中推测)可以减少延迟(同样具有误预测处理成本)。 Scratchpad(又名紧密耦合)内存没有标签或关联性,因此可以稍微快一些(并且访问能量较低),并且一旦确定访问该区域,就不可能错过。背包缓存的内容可以被视为上下文的一部分,并且在该缓存被填满之前,上下文不会被认为是准备好的。理论上,寄存器也可以延迟加载(尤其是安腾堆栈寄存器),因此必须处理寄存器未命中的可能性。
固定大小与可变大小
寄存器通常是固定大小的。这避免了移动从对齐存储中检索到的数据以将实际最低有效位放置到执行单元的适当位置的需要。此外,许多加载指令对加载的值进行符号扩展,这会增加延迟。 (零扩展不依赖于数据值。)
复杂因素
一些 ISA 确实支持子寄存器,尤其是 x86 和 zArchitecture(源自 S/360),这可能需要预移位。还可以以较低的延迟提供完全对齐的负载(可能以其他负载一个周期的额外延迟为代价);子字加载足够常见,并且增加的延迟足够小,以至于特殊大小写并不常见。符号扩展延迟可能隐藏在进位传播延迟之后;或者,可以使用符号预测(可能只是推测性的零扩展)或将符号扩展视为慢速情况。 (对未对齐负载的支持会使缓存访问更加复杂。)
小容量
有序 64 位 RISC 的典型寄存器文件只有大约 256 个字节(32 个 8 字节寄存器)。对于现代缓存而言,8KiB 被认为很小。这意味着将物理尺寸和静态功率相乘以提高速度对总面积和静态功率的影响要小得多。更大的晶体管具有更高的驱动强度,其他增加面积的设计因素可以提高速度。
复杂因素
一些 ISA 具有大量架构寄存器,并且可能具有非常宽的 SIMD 寄存器。此外,一些实现添加了额外的寄存器用于重命名或支持多线程。使用 SIMD 并支持多线程的 GPU 可以具有特别大容量的寄存器文件; GPU 寄存器文件也不同于 CPU 寄存器文件,它通常是单端口的,每个周期访问一个操作数/结果的向量元素的数量是可用于执行的四倍(例如,使用 512 位宽的乘加执行,读取三个操作数各 2KiB,并写入 2KiB 结果)。
常见案例优化
由于寄存器访问旨在成为常见情况,因此将面积、功耗和设计工作用于提高此功能的性能更有利可图。如果 5% 的指令不使用源寄存器(直接跳转和调用、寄存器清除等),70% 使用一个源寄存器(简单加载、立即数操作等),25% 使用两个源寄存器,75 % 使用目标寄存器,而 50% 访问数据内存(40% 加载,10% 存储)——基于 SPEC CPU2000 用于 MIPS 的数据的粗略近似——然后是 3 倍以上(对时间更关键) 读取来自寄存器而不是内存(每条指令 1.3 对 0.4)和
复杂因素
并非所有处理器都是为“通用”工作负载而设计的。例如,处理器使用内存中的向量并使用寄存器作为向量起始地址、向量长度和累加器的点积性能可能没有理由优化寄存器延迟(极端并行性简化了隐藏延迟)并且内存带宽将比寄存器更重要带宽。
小地址空间
寄存器的最后一个小优点是地址空间很小。这减少了索引存储阵列时地址解码的延迟。可以将地址解码想象为一系列二进制决策(存储块的一半或其他)。一个典型的高速缓存 SRAM 阵列有大约 256 个字线(列、索引地址)——8 位要解码——而且 SRAM 阵列的选择通常还涉及地址解码。一个简单的有序 RISC 通常有 32 个寄存器 — 5 位要解码。
复杂因素
现代高性能处理器可以轻松拥有 8 位寄存器地址(安腾在上下文中有超过 128 个通用寄存器,而高端无序处理器可以拥有更多寄存器)。相对于上述考虑,这也是一个不太重要的考虑因素,但不应忽视。
结论
上述许多考虑因素重叠,这是优化设计的预期。如果期望一个特定的功能是通用的,那么不仅实现会被优化,接口也会被优化。限制灵活性(直接寻址、固定大小)自然有助于优化,更小更容易更快。