为什么ARM有16个寄存器?

10

ARM为什么只有16个寄存器?这是理想的数量吗?

拥有更多寄存器的寄存器距离是否会增加处理时间/功耗?


这是一个编码在指令集中的2、3、4或5位的情况,以及对于固定大小指令,您可以拥有哪种混合和风味的指令。从许多指令集中我们看到,3或4位是比较优化的。 - old_timer
5个回答

21
随着通用寄存器数量的减少,您需要开始使用堆栈来存储变量。使用堆栈需要更多的指令,因此代码大小会增加。同时,使用堆栈还会增加内存访问次数,这对性能和功耗都有负面影响。权衡之处在于,为了表示更多的寄存器,您需要在指令中使用更多的位,并且需要在芯片上留出更多的空间用于寄存器文件,这会增加功耗。通过使用不同数量的寄存器编译相同的代码,您可以看到不同寄存器数量如何影响代码大小和加载/存储指令的频率。这种类型的练习的结果可以在本文的表1中看到: 可扩展指令集计算
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个寄存器是一种理想的平衡点。


你是在说寄存器越多越好吗? ;) - Austin Henley
我想详细说明一下堆栈和寄存器。如果寄存器的数量不足,则需要使用堆栈,但是如果开始使用堆栈,则需要进行内存读/写,即获取/存储以执行操作。这将导致更多的执行周期并作为开销。因此,需要在堆栈和寄存器之间进行权衡。 - shingaridavesh
1
如果你只在MIPS中像这样计算真实的GPRs,那么在ARM32中只有13个寄存器(R0-R12,减去SP,LR和PC),x86有7个(减去SP,省略帧指针时)。x86_64有15个,而ARM64有31个。 - phuclv
如果16是一个理想的数字,那么为什么ARM64要增加它呢?这个数字是基于很多原因和基准测试来选择的。 - phuclv
@Lưu Vĩnh Phúc - 第一款ARM处理器于20世纪80年代中期创建,晶体管数量约为30,000。当时,增加寄存器文件的大小以支持32个GPR将显着增加成本和功耗,而对代码密度的贡献不成比例。到ARM64设计时,已经有超过十亿个晶体管的芯片,因此增加寄存器文件大小的影响已经不是问题了。 - Bradley McKinley
@BradleyMcKinley,ARM和MIPS都是在1985年推出的,但MIPS有32个全局寄存器。只是ARM设计师选择了与MIPS不同的权衡:GPR数量与条件执行能力。添加谓词位会浪费指令编码空间和芯片面积,就像添加更多的GPR一样。MIPS使用3个额外的位来获取更多的寄存器,而ARM使用4个额外的位来表示条件。 - phuclv

4
32位ARM只有16个寄存器,因为它仅使用4位来编码寄存器,而不是因为16是理想的数量。同样,x86只有8个寄存器,因为在历史上,他们使用3位来编码寄存器,以便一些指令适合一个字节。
这是一个非常有限的数量,因此当x86和ARM转向64位时,将寄存器数量加倍到16和32个。旧的ARM指令编码没有剩余的位数足以支持更多的寄存器数量,因此必须做出权衡,放弃几乎每个指令的条件执行能力,并使用4位条件来支持新功能(这是一个过度简化的表述,实际上并不完全如此,因为编码是新的,但你确实需要3个额外的位来支持新的寄存器)。

4
选择其中一个16个寄存器需要4位,因此这可能是操作码(机器指令)的最佳匹配,否则您将不得不引入更复杂的指令集,这将导致更大的编码器,从而意味着额外的成本(执行时间)。 维基百科 表示它具有“固定的32位指令宽度,以便于解码和流水线处理”,因此这是一个合理的权衡。

1
是的,我们希望指令适合32位,但您可以按照自己的方式划分。例如,如果您有一个ISA可以具有两个源寄存器和一个目标寄存器,则可以使用15位指定这三个寄存器,然后您还有17位用于其他内容,如操作码等。 - Timothy Miller

2
在80年代(如果我没记错的话),发表了一篇学术论文,研究了许多不同的工作负载,比较了不同数量寄存器预期的性能改进。这是RISC处理器从学术思想转向主流硬件的时期,决定什么最优很重要。CPU已经在速度上超过了内存,而RISC通过限制寻址模式并拥有单独的load和store指令使情况变得更加糟糕。拥有更多的寄存器意味着你可以“缓存”更多数据以供即时访问,从而减少对主内存的访问。
只考虑2的幂次方,发现32个寄存器是最优的,虽然16个寄存器也不差。

0

ARM 的独特之处在于每个寄存器都可以具有条件执行代码,避免了测试和分支。不要忘记,许多 32 位寄存器机器将 R0 固定为 0,因此通过与 R0 进行比较来进行条件测试。我从经验中知道。20 年前,我不得不编写一个“Mode 7”(来自 SNES 术语)地板的程序。CPU 分别是 SH2 (32x 中的两个),MIPS3000 (Playstation) 和 3DO (ARM),代码的内部循环分别为 19、15 和 11。如果 3DO 运行速度与其他两个相同,那么它将是两倍的速度。但事实上,它只稍微慢一些。


1
这些19、15、11是循环中的指令数吗?这些不同的CPU有多少个寄存器?如果你澄清了这一点,那么这可能只是一个答案,而不是一个应该作为评论的轶事。此外,ARM的条件执行是按指令而不是按寄存器进行的。寄存器数量无关(除了它们都在32位指令字中占用位,正如其他答案所指出的那样)。 - Peter Cordes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接