为什么最常见的CPU(x86)中只有四个寄存器?如果添加更多寄存器,速度是否会大幅增加?何时会添加更多寄存器?
答案 0 :(得分:25)
x86的总是有超过四个寄存器。最初,它具有CS,DS,ES,SS,AX,BX,CX,DX,SI,DI,BP,SP,IP和标志。其中,七个(AX,BX,CX,DX,SI,DI和BP)支持大多数一般操作(加法,减法等)BP和BX也支持用作“基”寄存器(即,保持地址为间接)。 SI和DI也可以用作索引寄存器,它与基址寄存器大致相同,只是一条指令可以从一个基址寄存器和一个索引寄存器产生一个地址,但不能从两个索引寄存器或两个基址寄存器产生。至少在典型的使用中,SP专门用作堆栈指针。
从那时起,寄存器变得越来越大,增加了更多,并且其中一些寄存器变得更加通用,因此(例如)您现在可以在2寄存器寻址模式下使用任何2个通用寄存器。有点奇怪的是,在386中添加了两个段寄存器(FS和GS),这也允许32位段,这些段主要使得所有段寄存器几乎无关紧要。它们有时用于线程本地存储。
我还应该补充一点,当你进行多任务,多线程等时,很多寄存器都会受到严重的惩罚 - 因为你不知道哪些寄存器在使用,当你做一个上下文切换您必须将所有寄存器保存在一个任务中,并为下一个任务加载所有已保存的寄存器。在像Itanium或具有200多个寄存器的SPARC这样的CPU中,这可能相当慢。最近的SPARC投入了相当数量的芯片面积来优化它,但它们的任务切换仍然相对较慢。在Itanium上情况更糟 - 这是因为它在典型的服务器任务上不那么令人印象深刻,尽管它通过(非常)少量任务切换来进行科学计算。
当然,最后,所有这些与x86的合理现代实现的工作原理完全不同。从Pentium Pro开始,英特尔将实现中的架构寄存器(即,可以在指令中寻址的寄存器)去耦。为了支持并发,乱序执行,Pentium Pro具有(如果存储器服务)一组40个内部寄存器,并使用“寄存器重命名”,因此两个(或更多)那些可能在给定时间对应于给定的架构寄存器。例如,如果您操作一个寄存器,然后存储它,加载一个不同的值并操纵它,处理器就可以检测到该负载会破坏这两组指令之间的依赖关系链,因此它可以同时执行这两个操作。
Pentium Pro现在已经很老了 - 当然,AMD已经存在了一段时间(尽管他们的设计在这方面相当相似)。虽然细节随着新处理器的变化而变化,但具有将架构寄存器与物理寄存器分离的重命名功能现在或多或少成为现实。
答案 1 :(得分:9)
现在 超过4个。如果查看history of the x86 architecture,您会发现它已从8086指令集演变而来。英特尔一直希望在其处理器产品线中保持一定程度的向后兼容性,因此所有后续处理器只需将原始的A,B,C,D寄存器扩展为更多的位。原始段寄存器可以用于今天的一般用途,因为不再有真正的段(这是过于简单化,但大致相同)。新的x64架构也提供了一些额外的寄存器。
答案 2 :(得分:7)
X86实际上是一个8寄存器机器(eax / ebx / ecx / edx / esi / edi / ebp / esp)。你丢失其中一个到堆栈指针/基址指针,所以在实际使用中你得到7,这有点偏低,但即使一些RISC机器有8(SuperH和ARM在THUMB模式,因为他们有16位指令大小和更多的寄存器太长,无法编码!)。对于64位代码,您将从8升级到16(它们在指令编码AFAIK中使用了一些剩余的位)。
尽管如此,8个寄存器恰好足以管理CPU,这对486s和pentiums来说是完美的。其他一些架构,如6502/65816,在早期的32位时代就已经消失了,因为你无法制作一个快速的有序流水线版本(你只有3个寄存器,只有1个用于一般数学,所以一切都会导致失速! )。一旦你进入所有寄存器被重命名并且一切都无序(奔腾2等)的那一代,那么它就不再重要了,如果你一遍又一遍地重复使用相同的寄存器,你就不会得到停顿。然后8个寄存器就可以了。
更多寄存器的另一个用途是将循环常量保存在寄存器中,并且您不需要在x86上,因为每条指令都可以执行内存加载,因此您可以将所有常量保留在内存中。这是RISC缺少的一个功能(按照定义),虽然它们通过更容易管道(最长延迟是2个周期而不是3个)来弥补它,并且稍微超标量,但您的代码大小仍然会增加一些。 ..
添加更多寄存器有一些非显而易见的成本。你的指令变得更长,因为你需要更多的位,这会增加程序的大小,如果你的代码速度受到读取指令的内存带宽的限制,这会减慢程序的速度!
还有一个事实是,寄存器文件越大,读取值所需的多路复用器级别/通用电路就越多,这会增加延迟,这可能会降低时钟速度!
这就是为什么传统观点认为超过32个寄存器并不是一个好主意(没用,尤其是在无序CPU上),8只是太低(内存读取仍然很昂贵) !),以及为什么理想的架构被认为是75%RISC 25%CISC,以及为什么ARM很受欢迎(平衡恰到好处!),几乎所有RISC架构仍然有一些CISC部件(每个存储器OP中的地址计算) ,32位操作码,但不是更多!),为什么Itanium失败了(128位操作码?64个寄存器?在内存操作中没有地址计算???)。
由于所有这些原因,x86还没有被超越 - 确保指令编码完全是疯了,但除此之外,所有疯狂的重新排序和重命名以及投机性加载存储精神错误它确实保持高效实际上都是真的有用的功能正是使它在各种更简单的有序设计(例如POWER6)上具有优势。一旦你重新排序并重命名所有内容,所有指令集或多或少都是相同的,所以除了特定情况(基本上是GPU)之外,很难以任何方式实现更快的设计。一旦ARM cpu达到x86s的速度,它们就会像英特尔推出的那样疯狂和复杂。
答案 3 :(得分:4)
有许多架构具有更多寄存器(ARM,PowerPC等)。有时,它们可以实现更高的指令吞吐量,因为在操作堆栈时执行的工作更少,并且指令可能更短(无需引用堆栈变量)。由于节省了更多的寄存器,反转点是函数调用变得更加昂贵。
答案 4 :(得分:2)
更多寄存器不一定能使事情变得更快,它们使CPU架构更加复杂,因为寄存器必须靠近其他组件,而且许多指令只能在特定的寄存器上工作。
但现代CPU有四个以上的寄存器,从头到尾有AX,BX,CX,DX,SI,DI,BP ......然后CPU有内部寄存器,例如用于PIC(处理器指令计数器) )
答案 5 :(得分:0)
嗯,还有更多,这四个都是特别的,它们是'通用'我认为,所有这些的原因以及为什么其余部分没有被使用那么多:
答案 6 :(得分:0)
注册使用的内存在CPU中工程设计实际上。除了这样做的设计困难之外,增加可用寄存器的数量会使CPU芯片更加昂贵。
另外:
答案 7 :(得分:0)
嗯......(E / R)AX,(E / R)BX,(E / R)CX,(E / R)DX,(E / R)SI,(E / R)DI ,(E / R)SP,(E / R)BP,(E / R)IP。我认为超过4. :)
答案 8 :(得分:0)
这完全取决于架构设计。 Intel Itanium有128个通用寄存器和128个浮点寄存器,而Intel x86只有8个通用寄存器和8个浮点数。