【发布时间】:2012-01-18 00:20:11
【问题描述】:
为什么ARM只有16个寄存器?这是理想的数字吗?
具有更多寄存器的寄存器距离是否也会增加处理时间/功率?
【问题讨论】:
-
它是指令集中编码的 2、3、4 或 5 位的情况,以及对于固定大小的指令,您可以拥有什么样的指令组合和风格。正如我们从许多指令集中看到的那样,3 位或 4 位在某种程度上是最佳的。
标签: arm cpu-registers cpu-architecture
为什么ARM只有16个寄存器?这是理想的数字吗?
具有更多寄存器的寄存器距离是否也会增加处理时间/功率?
【问题讨论】:
标签: arm cpu-registers cpu-architecture
32 位 ARM 有 16 个寄存器,因为它只使用 4 位来对寄存器进行编码,而不是因为 16 是理想的数字。同样,x86 只有 8 个寄存器,因为在历史上他们使用 3 位对寄存器进行编码,以便某些指令适合一个字节。
这是一个如此有限的数量,因此 x86 和 ARM 在进入 64 位时都将数量翻了一番,分别为 16 和 32 个寄存器。旧的 ARM 指令编码没有足够的剩余位来容纳更大的寄存器数,因此他们必须做出权衡,放弃有条件地执行几乎每条指令的能力,并为新功能使用 4 位条件(这是一种过度简化,实际上并不完全一样,因为编码是新的,但新寄存器确实需要多 3 位)。
【讨论】:
ARM 的独特之处在于每个寄存器都可以有一个条件执行代码,避免测试和分支。不要忘记,许多 32 寄存器机器将 R0 固定为 0,因此条件测试是通过与 R0 进行比较来完成的。我从经验中知道。 20 年前,我不得不对“模式 7”(来自 SNES 术语)地板进行编程。 CPU 是 SH2 用于 32x(或者更确切地说是 2 个)、MIPS3000(Playstation)和 3DO(ARM),代码的内循环是 19,15 和 11。如果 3DO 一直以与其他 2,它会快两倍。事实上,它只是慢了一点。
【讨论】:
随着通用寄存器的数量越来越少,您需要开始将堆栈用于变量。使用堆栈需要更多指令,因此代码大小会增加。使用堆栈还会增加内存访问次数,这会损害性能和功耗。权衡是为了表示更多的寄存器,您需要在指令中使用更多位,并且您需要在芯片上为寄存器文件提供更多空间,这会增加功率要求。您可以通过使用不同数量的寄存器编译同一组代码来了解不同的寄存器数量如何影响代码大小和加载/存储指令的频率。此类练习的结果可以在本文的表 1 中看到:
Extendable Instruction Set Computing
Register Program Load/Store
Count Size Frequency
27 100.00 27.90%
16 101.62 30.22%
8 114.76 44.45%
(他们使用 27 作为基础,因为这是 MIPS 处理器上可用的 GPR 数量)
如您所见,当您将寄存器计数降至 16 个时,程序大小和所需的加载/存储数量仅略有改善。真正的惩罚只有在您降至 8 个寄存器时才会生效.我怀疑 ARM 设计人员认为 16 个寄存器是您在寻找最佳每瓦性能时的最佳选择。
【讨论】:
早在 80 年代 (IIRC) 就发表了一篇学术论文,研究了许多不同的工作负载,比较了不同数量的寄存器的预期性能优势。当时正值 RISC 处理器从学术思想过渡到主流硬件的时候,决定什么是最优的很重要。 CPU 的速度已经领先于内存,而 RISC 通过限制寻址模式和单独的加载和存储指令使情况变得更糟。拥有更多寄存器意味着您可以“缓存”更多数据以便立即访问,从而减少对主内存的访问。
仅考虑 2 的幂,发现 32 个寄存器是最佳的,虽然 16 个也差不了多少。
【讨论】:
要选择 16 个寄存器中的一个,您需要 4 位,因此这可能是操作码(机器命令)的最佳匹配,否则您将不得不引入更复杂的指令集,这将导致更大的编码器,这意味着额外的成本(执行时间)。
Wikipedia 说它具有“32 位的固定指令宽度以简化解码和流水线” 所以这是一个合理的权衡。
【讨论】: