为什么只有四个寄存器?

cam*_*cam 17 x86 cpu-architecture

为什么在最常见的CPU(x86)中只有四个寄存器?如果添加更多寄存器,速度不会大幅增加吗?何时会添加更多寄存器?

Jer*_*fin 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已经存在了一段时间(尽管他们的设计在这方面相当相似).虽然细节随着新处理器的变化而变化,但具有将架构寄存器与物理寄存器分离的重命名功能现在或多或少成为现实.


Vic*_*Liu 9

目前超过4时下.如果你看一下x86架构历史,你会发现它已经从8086指令集发展而来.英特尔一直希望在其处理器产品线中保持一定程度的向后兼容性,因此所有后续处理器只需将原始的A,B,C,D寄存器扩展为更多的位.原始段寄存器可以用于今天的一般用途,因为不再有真正的段(这是过于简单化,但大致相同).新的x64架构也提供了一些额外的寄存器.

  • 由于寄存器重命名,有多个x. (5认同)
  • 此外,数学协处理器有自己的一组寄存器. (3认同)

小智 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的速度,它们就会像英特尔推出的那样疯狂和复杂.