2010-05-20 92 views
15

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

+8

X86甚至不是最常见的处理器。最近检查过你的手机吗? – 2010-05-20 23:03:49

+3

这是最常见的个人计算,如果不包括移动设备 – 2013-08-22 00:27:49

+0

[为什么x86 int寄存器的数量是8?](https://stackoverflow.com/q/16248337/995714) – 2018-02-11 09:57:27

回答

8

比4时下比较。如果你看看history of the x86 architecture,你会发现它已经从8086指令集发展而来。英特尔一直希望在其处理器产品线中保持一定程度的向后兼容性,因此所有后续处理器都将原始A,B,C,D寄存器扩展为更宽的位数。原来的段寄存器可以用于今天的一般用途,因为再也没有真正的段(这是过分简单化,但大体上是真实的)。新的x64架构也提供了一些额外的寄存器。

+3

另外,数学协处理器有它自己的一套寄存器。 – BoltBait 2010-05-20 22:44:26

+5

由于寄存器重命名,有超过x个。 – 2010-05-20 22:53:21

+0

和SSE寄存器,MSR,DRx,CRx ... – 2010-05-20 22:53:59

4
  1. 寄存器曾经是实施起来很昂贵。
  2. 不一定。现代x86 CPU上的寄存器数量远远超出了CPU所显示的数量--CPU维护影子寄存器,根据指令流程需要根据需要重命名影子寄存器。
  3. 在AMD64/x86_64中。在64位模式下运行时,通用寄存器的数量加倍(除了它们的大小加倍)。

有许多架构有更多的寄存器(ARM,PowerPC等)。有时,它们可以实现更高的指令吞吐量,因为操作堆栈所做的工作量更少,并且指令可能更短(无需引用堆栈变量)。由于更多的寄存器保存,对应点是函数调用变得更加昂贵。

0

嗯,有更多的,四只是特殊,他们是“通用”我认为,这种情况的原因所有,为什么不使用剩下的这一点是:

  • 86 WASN作为事实标准的最佳指令,Intell刚刚看到了向后兼容的可能性,一旦AMD加入进来只是时间问题。
  • 现在这是事实上的标准,所以我们必须忍受它。
  • 添加更多的寄存器将不再是x86,所以你的意思是'用更多的寄存器创建一个基于x86的新指令集'。
  • 大多数编译器不会使用这些编译器,因为它们可以编译为x86,也可以编译x86的超集。
  • 更多寄存器意味着更昂贵的硬件。
+1

我认为说“x86非常流行,变成其他任何证明无利可图的东西”会更准确。请记住,英特尔试图启动Itanium,它有128个int寄存器,并且是真正的64位,但由于缺乏向后兼容而失败。 – Jimmy 2010-05-20 22:56:25

0

注册使用的内存是真的是在CPU中设计昂贵。除了这样做的设计困难之外,增加可用寄存器的数量使得CPU芯片更昂贵。

另外:

  • 还有其他的方法来提高CPU的性能,这更符合成本效益
  • 即使多个地方出台,你仍然需要更新指令集,并修改了使用编译器。
  • 已经有多于4个寄存器:维基百科(世界诶,最可靠的来源)
    • AX/EAX/RAX:累加器
    • BX/EBX/RBX:基本索引(例如:阵列)
    • CX/ECX/RCX:计数器
    • DX/EDX/RDX:数据/一般
    • SI/ESI/RSI: “源索引” 为字符串操作。
    • DI/EDI/RDI:字符串操作的“目标索引”。
    • SP/ESP/RSP:堆栈顶部地址的堆栈指针。
    • BP/EBP/RBP:用于保存当前堆栈帧地址的堆栈基址指针。
    • IP/EIP/RIP:指令指针。保存程序计数器,当前指令地址。
+0

“真正昂贵”在1980年是真实的。现代CPU具有巨大(L1大小)的核心时钟内存,虽然价格昂贵,但并不能解释感知寄存器的不足。 – 2010-05-20 22:45:59

+0

相对而言,它是昂贵的/非常昂贵的。寄存器内存的使用与L1缓存不同。当然,除非寄存器自从我上次检入之后已经开始缓存未命中...... – 2010-05-20 22:56:40

+0

更多体系结构寄存器对于当前的x86硬件(除了insn编码困难之外)不会有问题。目前的设计已经有超过100个物理寄存器被重新命名。这个“非常昂贵”的东西是为什么拱形结构登记册数量很少的历史原因。这意味着更少的状态来保存/恢复上下文切换。 – 2015-08-14 07:54:36

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 :)

2

更多的寄存器不一定使事情更快,它们使CPU架构更加复杂,因为寄存器必须接近其他部件和许多指令只对特定的寄存器工作。但是现代的CPU有四个以上的寄存器,从头到尾有AX,BX,CX,DX,SI,DI,BP ......然后CPU有内部寄存器,例如PIC(处理器指令专柜)

21

x86的有总是有四个以上的寄存器。最初,它有CS,DS,ES,SS,AX,BX,CX,DX,SI,DI,BP,SP,IP和标志。其中,7个(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开始,Intel分离了架构寄存器(即,那些可以在指令中解决的问题)。为了支持并发的乱序执行,Pentium Pro拥有(如果有内存服务的话)一组40个内部寄存器,并使用“寄存器重命名”,这样两个(或更多)这些寄存器可以在给定时间对应给定的架构寄存器。例如,如果操作寄存器,然后存储它,加载一个不同的值并对其进行处理,那么处理器可以检测到负载打破了这两组指令之间的依赖链,因此它可以同时执行这两个操作。

奔腾Pro是现在很老了,当然 - 当然,AMD也已经有一段时间了(虽然他们的设计在这方面相当类似)。虽然细节随新处理器而改变,但具有将体系结构寄存器与物理寄存器分离的重命名功能现在已成为生活中的事实。

+1

真的很好的答案 - 有趣的理解#注册多线程perf# – 2010-08-02 18:04:02

+1

你的意思是“安腾”提到“Itanic”时暗示 – 2013-08-22 00:29:09

0

它仅仅依赖于建筑descisions。 Intel Itanium有128个通用寄存器和128个浮点寄存器,而Intel x86只有8个通用寄存器和8个浮点寄存器。

+0

x87堆栈的时代早在几十年前就已经过去了。如今x86处理器使用速度更快的SSE或其后继者,它们都使用xmm/ymm寄存器而不是堆栈 – 2013-08-22 03:28:56

7

X86是一个真正的8寄存器机(EAX/EBX/ECX/EDX/ESI/EDI/EBP/ESP)。你在堆栈指针/基址指针中丢失了1个,所以在实际使用中你得到了7,这有点偏低,但即使是一些RISC机器也有8个(THUMB模式下的SuperH和ARM,因为它们有16位指令大小和更多的寄存器将太长,无法编码!)。对于64位代码,您从8升级到16(它们使用指令编码AFAIK中的一些剩余位)。

尽管如此,8个寄存器是恰到好处刚够管道的CPU,这是完美的486和奔腾。其他一些架构,比如6502/65816,在32位时代早期就已经离开了,因为你不能制作一个快速的有序流水线版本(你只有3个寄存器,而且只有1个用于一般数学运算,所以一切都会导致失速! )。一旦你到达所有你的寄存器被重新命名并且一切都无序(pentium 2等)的世代,那么它就不再重要了,如果你一遍又一遍地重复使用同一个寄存器,你将不会得到停顿,那么8个寄存器就相当好了。

其他使用了更多的寄存器是保持环常量寄存器中,你不需要在x86,因为每一个指令可以做内存负载,这样你就可以将所有的常量在内存中。这是RISC(根据定义)所缺少的一个特性,虽然它们通过更易于管道化(最长的延迟是2个周期而不是3个)并略微超标量来弥补它的不足,但代码大小仍会增加一些。 ..

添加更多寄存器有一些非显而易见的成本。你的指令会变得更长,因为你需要更多的位,这会增加程序的大小,如果你的代码速度受到读指令的内存带宽的限制,会使程序变慢。

还有一个事实,即较大的寄存器文件,你必须要经过更多的多路复用器的水平/一般电路读取值,这增加了等待时间,这可能降低时钟速度!

这就是为什么atm的传统观点是,超过32个寄存器不是一个好主意(没有用,特别是在无序CPU上),而8只是太低(内存读取仍然是昂贵的!),以及为什么理想的架构被认为是75%RISC 25%CISC,以及为什么ARM是流行的(几乎所有RISC架构仍然有一些CISC架构)(每个内存中的地址计算OP,32位操作码,但不是更多!),安腾失败的原因(128位操作码?64个寄存器?内存操作中没有地址计算?)。

由于所有这些原因,x86没有被超越 - 确保指令编码完全是疯狂的,但除此之外,所有疯狂的重新排序和重命名以及保持高效的加载存储疯狂实际上都是真正有用的功能,正是它在各种简单的有序设计(如POWER6)上的优势。一旦你重新排序和重命名所有的东西,所有的指令集或多或少都是相同的,所以很难让设计实际上以任何方式更快,除了特定的情况(基本上是GPU)。一旦ARM cpus获得与x86相同的速度,它们就会像英特尔推出的那样疯狂和复杂。

+1

x86_64使用[REX前缀](http://wiki.osdev.org/X86-64_Instruction_Encoding#REX_prefix)对新的因为旧的x86编码对于新的寄存器大小没有剩余位 – 2013-08-22 03:42:36

+1

Intel/AMD的x86实现尽管insn的复杂性很快,但不是因为它的原因。他们确实获得了为解码后的uops选择自定义内部表示的灵活性,但是如果有增益,他们可以将更明智的指令编码转换为uops。在某些情况下,可变大小的insn编码有一些优点:它有点像压缩,当它们简单并且平均小于4B时,为每个缓存行打包更多指令。仍然insn解码可能是一个主要的瓶颈,除非在Sandybridge和以后用完uop缓存。 – 2015-08-14 07:51:37

相关问题