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

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

===============>>#1 票数:16 已采纳

随着通用寄存器的数量变小,您需要开始使用堆栈作为变量。 使用堆栈需要更多指令,因此代码大小会增加。 使用堆栈还会增加内存访问次数,从而影响性能和功耗。 权衡的是,为了代表更多的寄存器,您需要在指令中使用更多的位,并且芯片上需要更多的空间用于寄存器文件,这会增加功耗要求。 通过使用不同数量的寄存器编译同一组代码,您可以看到不同的寄存器计数如何影响代码大小和加载/存储指令的频率。 这种练习的结果可以在本文表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个寄存器是一种最佳点。

===============>>#2 票数:4

32位ARM有16个寄存器,因为它只使用4位来编码寄存器,而不是因为16是理想的数字。 同样,x86只有8个寄存器,因为在历史上它们使用3位来编码寄存器,以便某些指令适合一个字节。

这是一个有限的数字,所以x86和ARM在64位时分别将数字加倍到16和32个寄存器。 旧的ARM指令编码没有足够的剩余位用于较大的寄存器编号,因此它们必须通过放弃几乎每条指令有条件地执行并使用4位条件进行新功能来进行权衡(这是过于简单化的,实际上它并不完全是这样,因为编码是新的,但是你需要为新寄存器再增加3位。

===============>>#3 票数:4

要选择16个寄存器中的一个,你需要4位,因此这可能是操作码(机器命令)的最佳匹配,否则你将不得不引入更复杂的指令集,这将导致更大的编码器,这意味着额外的成本(执行)时间)。

维基百科称它具有“固定指令宽度为32位以简化解码和流水线操作”,因此这是一个合理的权衡。

===============>>#4 票数:2

早在80年代(IIRC)就发表了一篇学术论文,该论文研究了许多不同的工作量,比较了不同数量寄存器的预期性能优势。 这正是RISC处理器从学术思想转变为主流硬件的时候,决定什么是最优的很重要。 CPU已经在速度上领先于内存,RISC通过限制寻址模式和单独的加载和存储指令使情况变得更糟。 拥有更多寄存器意味着您可以“缓存”更多数据以便立即访问,从而减少访问主内存。

仅考虑2的幂,发现32个寄存器是最佳的,尽管16个并不是非常落后。

===============>>#5 票数:0

ARM的独特之处在于每个寄存器都可以有一个条件执行代码,避免测试和分支。 不要忘记,许多32个寄存器机器将R0固定为0,因此通过与R0进行比较来完成条件测试。 我从经验中知道。 20年前,我不得不编写一个'模式7'(来自SNES术语)楼层。 对于32x(或者更确切地说是2个),MIPS3000(Playstation)和3DO(ARM),CPU是SH2,代码的内部循环是19,15和11.如果3DO的运行速度与其他2,它的速度会快一倍。 事实上,它只是有点慢。

  ask by Carbonizer translate from so

未解决问题?本站智能推荐:

1回复

处理器寄存器和指令寄存器有什么区别?

CPU中的处理器寄存器和指令寄存器有什么区别? 每个人都干了什么? 指令寄存器是处理器寄存器的一部分吗?
1回复

英特尔的上次分支记录功能是英特尔处理器独有的吗?

上一个分支记录是指寄存器对(MSR)的集合,这些寄存器对存储与最近执行的分支相关的源地址和目标地址。 它们在Intel Core 2,Intel Xeon和Intel Atom处理器家族中受支持​​。 如果您有兴趣, http://css.csail.mit.edu/6.858/2012/r
1回复

在arm-linux中使用ptrace获取寄存器

试图在arm linux中获取线程的PC注册。 有一个进程,进程ID = 120,它具有3个线程:线程ID:121,122,123。 在gcc-arm编译器中编译时,出现错误error: storage size of 'regs' isn't known struct user_
2回复

记录ARM Linux中的CPU寄存器更改

我想知道如何监视ARM linux中应用程序的多个寄存器更改。 我知道我必须调试它,但是如何在ARM linux中自动记录所有寄存器更改? 我知道使用gdb中的watch命令可以做到这一点,但是有可能制作一个小的C代码,使其仅运行调试器之类的应用程序,并记录其寄存器更改吗? 简而言
2回复

ARM汇编中是否有小型寄存器?

我最近开始玩ARM汇编,并注意到我似乎只打算将32位值移到寄存器中,但是如果我只想像在x86汇编中那样只将8位或16位移到寄存器中该怎么办。 即 r0现在包含0x80,但它是一个32位寄存器,因此它将包含0x00000080 如果这是x86,我可以使用al(8位寄存器)来操纵最后
5回复

处理ARM芯片的保留寄存器位

我正在使用ARM Cortex M3的寄存器。 在文档中,某些位可能被“保留”。 我不清楚写寄存器时应如何处理这些保留位。 这些保留位是否可写? 我应该小心不要触摸它们吗? 如果我触摸它们,会发生不好的事情吗?
4回复

ARM Assembly,寄存器未设置为0吗?

嗨,我正在尝试编写代码,以便在控制台中输入空格时,将在R7中添加1,并将R4设置为0。 当添加空格时,R4设置为0xFFFFFFF0,但是当我向其添加'5'时,我得到0xFFFFFFF65。 我希望只得到0x00000005。 这很奇怪,因为当我在比较之外放置相同的命令时,它就起作用
1回复

如何获取寄存器的地址:ARM Cortex A8?

我想获得ARM Cortex a8的协处理器寄存器的物理地址,比如c9-用户使能寄存器(USEREN)。 我怎么才能得到它 ? 谢谢 !!
2回复

Printf更改寄存器中的值,ARM汇编

我是汇编编程的新手,并且正在为ARM编程。 我正在编写一个带有两个子例程的程序:一个将子程序信息附加到内存中的字节向量上,另一个将打印该向量。 向量的第一个地址包含其后的元素数,最多为255。使用GDB对其进行调试时,我可以看到“ appendbyte”子例程运行良好。 但是,当涉及到“
2回复

从LKM读取ARM CPU寄存器

我想从Linux内核模块读取存储在链接寄存器或帧指针中的值,但不确定使用的语法。 对于上下文,我已经编译了Android goldfish 3.4内核,并且正在使用insmod将模块加载到内核中。