【发布时间】:2011-02-22 03:08:05
【问题描述】:
为什么最常见的 CPU (x86) 中只有四个寄存器?如果添加更多寄存器,速度不会有很大的提高吗?什么时候会增加更多的寄存器?
【问题讨论】:
-
X86 甚至不是最常见的处理器。最近检查过你的手机吗?
-
如果不算移动设备,这在个人计算中是最常见的
标签: x86 cpu-architecture
为什么最常见的 CPU (x86) 中只有四个寄存器?如果添加更多寄存器,速度不会有很大的提高吗?什么时候会增加更多的寄存器?
【问题讨论】:
标签: x86 cpu-architecture
现在有 4 个以上 。如果您查看history of the x86 architecture,您会发现它是从 8086 指令集演变而来的。英特尔一直希望在其处理器系列中保持一定程度的向后兼容性,因此所有后续处理器都只是将原始 A、B、C、D 寄存器扩展到更多位数。原来的段寄存器现在可以用于一般目的,因为不再有真正的段(这是一个过度简化,但大致正确)。新的 x64 架构还提供了一些额外的寄存器。
【讨论】:
ESI / EDI / EBP,不是CS/DS/SS/GS/FS。)你可以对段寄存器做的就是移入或移出它们,而不是将它们用作@等指令的操作数987654328@.
有许多具有更多寄存器的架构(ARM、PowerPC 等)。有时,它们可以实现更高的指令吞吐量,因为在操作堆栈时完成的工作更少,并且指令可能更短(无需引用堆栈变量)。与之相对的是,由于更多的寄存器节省,函数调用变得更加昂贵。
【讨论】:
嗯,还有更多,这四个只是特殊的,我认为它们是“通用”的,所有这些的原因以及为什么其余部分没有那么多使用是:
【讨论】:
寄存器使用的内存真的在 CPU 中设计起来非常昂贵。除了这样做的设计困难之外,增加可用寄存器的数量会使 CPU 芯片更加昂贵。
另外:
【讨论】:
嗯..... (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 个。:)
【讨论】:
更多的寄存器并不一定会让事情变得更快,它们会使 CPU 架构更加复杂,因为寄存器必须靠近其他组件,而且许多指令只能在特定的寄存器上工作。
但是现代 CPU 有四个以上的寄存器,从我的头顶上看,有 AX、BX、CX、DX、SI、DI、BP……然后 CPU 有内部寄存器,例如 PIC(处理器指令计数器)
【讨论】:
x86 总是有四个以上的寄存器。原来有CS、DS、ES、SS、AX、BX、CX、DX、SI、DI、BP、SP、IP和Flags。其中,7 个(AX、BX、CX、DX、SI、DI 和 BP)支持大多数通用运算(加法、减法等)。BP 和 BX 还支持用作“基”寄存器(即保存间接)。 SI 和 DI 也可以用作变址寄存器,它们与基址寄存器大致相同,只是一条指令可以从一个基址寄存器和一个变址寄存器生成地址,但不能从两个变址寄存器或两个基址寄存器生成地址。至少在典型使用中,SP 致力于充当堆栈指针。
从那时起,寄存器变得更大,增加了更多,其中一些变得更加通用,因此(例如)您现在可以在 2 寄存器寻址模式下使用任意 2 个通用寄存器。有点奇怪的是,在 386 中添加了两个段寄存器(FS 和 GS),这也允许 32 位段,这主要使所有段寄存器几乎无关紧要。它们有时用于线程本地存储。
我还应该补充一点,当您执行多任务、多线程等操作时,大量寄存器可能会产生相当严重的损失——因为您不知道哪些寄存器正在使用,当您执行上下文时切换您必须将所有寄存器保存在一个任务中,并为下一个任务加载所有保存的寄存器。在像 Itanium 或 SPARC 这样具有 200 多个寄存器的 CPU 中,这可能相当慢。最近的 SPARC 投入了相当多的芯片面积来优化这一点,但它们的任务切换仍然相对较慢。 Itanium 上的情况更糟——这是它在典型的服务器任务上不那么令人印象深刻的原因之一,尽管它在(非常)很少的任务切换的情况下在科学计算上大放异彩。
最后,当然,所有这一切都与 x86 的合理现代实现的工作方式完全不同。从 Pentium Pro 开始,英特尔将架构寄存器(即可以在指令中寻址的寄存器)与实现分离。为了支持并发、乱序执行,Pentium Pro 有(如果有记忆的话)一组 40 个内部寄存器,并使用“寄存器重命名”,因此其中两个(或更多)可能对应于给定时间的给定架构寄存器.例如,如果你操作一个寄存器,然后存储它,加载一个不同的值,然后操作它,处理器可以检测到加载破坏了这两组指令之间的依赖链,因此它可以同时执行这两个操作。
当然,Pentium Pro 现在已经很老了——当然,AMD 也已经存在了一段时间(尽管它们的设计在这方面相当相似)。虽然细节随着新处理器的变化而变化,但将架构寄存器与物理寄存器分离的重命名功能现在或多或少已成为现实。
【讨论】:
这完全取决于架构决定。 Intel Itanium 有 128 个通用寄存器和 128 个浮点寄存器,而 Intel x86 只有 8 个通用寄存器和 8 个浮点堆栈。
【讨论】:
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 个,所以一切都会导致停顿! )。一旦你到了所有寄存器都被重命名并且一切都乱七八糟的一代(奔腾2等),那么它就不再重要了,如果你一遍又一遍地重用同一个寄存器,你就不会遇到停顿,并且那么8个寄存器就可以了。
更多寄存器的另一个用途是将循环常量保存在寄存器中,您不需要在 x86 上,因为每条指令都可以执行内存加载,因此您可以将所有常量保存在内存中。这是 RISC 缺少的一个特性(根据定义),虽然它们通过更容易流水线(最长的延迟是 2 个周期而不是 3 个)和稍微超标量来弥补它,但您的代码大小仍然会增加一点。 ..
添加更多寄存器会产生一些不明显的成本。您的指令会变长,因为您需要更多位,这会增加程序大小,如果您的代码速度受到读取指令的内存带宽的限制,则会减慢您的程序!
还有一个事实是,您的寄存器文件越大,读取值所需通过的多路复用器级别/通用电路就越多,这会增加延迟,从而可能会降低时钟速度!
这就是为什么 atm 的传统观点是超过 32 个寄存器并不是一个好主意(没有用,尤其是在无序 CPU 上),而 8 太低了(内存读取仍然很昂贵!),以及为什么理想的架构被认为是 75% RISC 25% CISC 之类的东西,以及为什么 ARM 很受欢迎(平衡得刚刚好!),几乎所有 RISC 架构仍然有一些 CISC 部分(每个内存 OP 中的地址计算,32 位操作码,但不是更多!),为什么 Itanium 失败(128 位操作码?64 个寄存器?内存操作中没有地址计算???)。
由于所有这些原因,x86 并没有被超越——当然指令编码是完全疯狂的,但除此之外,它为保持效率所做的所有疯狂的重新排序和重命名以及推测性的加载存储疯狂实际上都是真的有用的特性,这正是它在各种更简单的有序设计(如 POWER6)中的优势所在。一旦你重新排序和重命名所有内容,所有指令集或多或少都是相同的,因此很难做出以任何方式实际上更快的设计,除了特定情况(本质上是 GPU)。一旦 ARM cpu 变得像 x86s 一样快,它们就会像 Intel 推出的一样疯狂和复杂。
【讨论】: