为什么CPU注册快速访问?

时间:2010-08-19 03:10:34

标签: cpu-architecture cpu-registers

注册变量是一种众所周知的快速访问方式(register int i)。但为什么寄存器位于层次结构的顶层(寄存器,缓存,主存储器,辅助存储器)?访问寄存器如此之快的所有事情是什么?

6 个答案:

答案 0 :(得分:19)

寄存器是直接连接到ALU的电路,ALU包含算术电路。每个时钟周期,CPU内核的寄存器单元可以将六个左右的变量馈入其他电路。实际上,数据路径中的单元(ALU等)可以通过旁路网络直接向彼此提供数据,这在某种程度上形成了寄存器之上的层级 - 但它们仍然使用寄存器 - 数字相互对应。 (完全流水线CPU的控制部分动态地将数据路径单元映射到寄存器号。)

C中的register关键字没有任何用处,您不应该使用它。编译器决定寄存器中的变量和时间。

答案 1 :(得分:9)

寄存器是CPU的核心部分,CPU的大部分指令集将针对寄存器而不是存储器位置进行定制。访问寄存器的值通常只需要很少的时钟周期(可能只需1),一旦访问内存,事情变得更加复杂,高速缓存控制器/内存总线就会被占用,操作将花费更多的时间。

答案 2 :(得分:2)

寄存器本质上是内部CPU内存。因此,访问寄存器比任何其他类型的存储器访问更容易和更快。

答案 3 :(得分:2)

几个因素导致寄存器比缓存快。

直接与间接寻址

首先,根据指令中的位直接对寄存器进行寻址。许多ISA在一个恒定的位置编码源寄存器地址,从而允许它们在指令被解码之前被发送到寄存器文件,从而推测将使用一个或两个值。最常见的存储器寻址模式是通过寄存器间接实现的。由于基址+偏移地址的频率,许多实现针对这种情况优化了流水线。 (在不同阶段访问缓存会增加复杂性。)缓存还使用标记,并且通常使用集合关联性,这往往会增加访问延迟。不必处理丢失的可能性也降低了寄存器访问的复杂性。

复杂因素

乱序的实现和具有堆叠或旋转寄存器(例如SPARC,Itanium,XTensa)的ISA会重命名寄存器。专用缓存,例如Todd Austin的背包缓存(使用偏移量直接索引缓存)和某些堆栈缓存设计(例如,使用小的堆栈帧号,并使用该帧号和偏移量直接索引专用堆栈缓存的一部分)避免寄存器读取和添加。签名高速缓存将寄存器名称和偏移量与一小部分存储相关联,从而为访问结构的较低成员提供了较低的延迟。索引预测(例如,对偏移量和基数进行XOR运算,避免进位传播延迟)可以减少等待时间(以处理错误预测为代价)。还可以为更简单的寻址模式(如寄存器间接寻址)更早地提供内存地址,但是在两个不同的流水线阶段访问高速缓存会增加复杂性。 (Itanium仅提供了寄存器间接寻址,并带有选项后置增量。)方式预测(在直接映射的高速缓存情况下进行命中推测)可以减少延迟(同样会产生错误预测的处理成本)。 Scratchpad(也称为紧密耦合)存储器没有标签或关联性,因此可以稍快一些(并且具有较低的访问能量),并且一旦确定要访问该区域,就不可能丢失。背包缓存的内容可被视为上下文的一部分,并且直到该缓存被填满,该上下文才被视为就绪。从理论上讲,寄存器也可以延迟加载(尤其是对于Itanium堆栈式寄存器),因此必须处理寄存器未命中的可能性。

固定大小与可变大小

寄存器通常是固定大小的。这避免了将从对齐存储器中检索到的数据移位以将实际的最低有效位放入执行单元的适当位置的需要。另外,许多加载指令符号会扩展加载的值,这会增加延迟。 (零扩展名不取决于数据值。)

复杂因素

某些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数据粗略地粗略近似-则是后者的三倍以上(对时序要求更高) )的读取是从寄存器而不是内存中读取的(每条指令为1.3,而内存为0.4)和

复杂因素

并非所有处理器都为“通用”工作负载而设计。例如,使用内存中向量的处理器以及使用用于向量起始地址,向量长度的寄存器和累加器来针对点积性能的处理器,几乎没有理由优化寄存器等待时间(极端并行性简化了隐藏等待时间),并且存储器带宽比寄存器更重要带宽。

小地址空间

最后一个寄存器的次要优点是地址空间很小。这减少了索引存储阵列时地址解码的等待时间。一个人可以将地址解码视为一系列二进制决策(存储块的另一半或另一半)。典型的高速缓存SRAM阵列具有大约256个字线(列,索引地址)(需要解码的8位),并且SRAM阵列的选择通常还会涉及地址解码。一个简单的有序RISC通常将具有32个寄存器-需要解码的5位。

复杂因素

现代高性能处理器可以轻松地拥有8位寄存器地址(Itanium在上下文中具有超过128个通用寄存器,而高端乱序处理器可以具有更多寄存器)。相对于上述考虑,这也是次重要的考虑因素,但不应忽略。

结论

许多上述考虑是重叠的,这对于优化设计是可以预期的。如果期望某个特定功能是通用的,那么不仅会优化实现,还会优化接口。限制灵活性(直接寻址,固定大小)自然有助于优化,而较小的则更容易更快地实现。

答案 4 :(得分:1)

较小的记忆通常比较大的记忆更快;它们还可以需要更少的位来寻址。一个32位指令字可以容纳三个四位寄存器地址,并为操作码和其他东西提供了大量空间;一个32位的内存地址将完全填满一个指令字,没有其他任何空间。此外,寻址存储器所需的时间以与存储器大小的对数成比例的速率增加。从4个字的存储空间访问一个字将比从一个16字的寄存器文件访问一个字的时间长几十甚至几百倍。

可以处理来自小型快速寄存器文件的大多数信息请求的机器将比使用较慢内存来处理所有内容的机器快。

答案 5 :(得分:0)

每个微控制器都有一个像Bill所提到的CPU,它具有ALU的基本组件,一些RAM以及其他形式的内存来协助其操作。 RAM就是你所指的主内存。

ALU处理所有关节逻辑操作并对任何操作数进行操作以执行这些计算,它将操作数加载到寄存器中,对这些操作执行操作,然后程序直接或间接访问这些寄存器中的存储结果

由于寄存器最接近CPU的核心(也就是处理器的大脑),它们在链中较高,而直接在寄存器上执行的操作只占用最少的时钟周期。