当然,至少流水线获取/解码,可能还有数据加载会更有帮助,因为每条指令都会嵌入一个数据内存地址。
(一些指令可能允许内存间接寻址模式,即从内存中加载一个指针,然后取消引用它,允许在没有自修改代码的情况下进行间接寻址。在进行第二次加载时,有序流水线可能不得不停止.如果你想保持管道的连贯性,自修改代码对于流水线尤其是 OoO exec 来说很糟糕。你可以保持简单,只保证跳转后的一致性,并丢弃跳转时的获取/解码结果以确保您正在观察新存储的指令,如果您想支持自修改代码,例如某些玩具累加器 ISA 需要循环遍历数组。(例如 Little Man Computer))
考虑到软件只有一个架构寄存器可供使用,因此无序执行的寄存器重命名可能很有价值。考虑到有效的内存消歧(存储转发检测),具有存储转发的存储缓冲区将为内存/缓存提供等效项。请参阅this Q&A 了解更多关于存储缓冲区的作用,以及来自那里的链接,包括https://blog.stuffedcow.net/2014/01/x86-memory-disambiguation/。
请注意,现代 x86 CPU 能够将 add eax, [mem] memory-source add 等指令流水线化到累加器中,并 mov [mem], eax 存储累加器。 (x86 有其他寄存器,但理论上你可以只用一个)。现代 x86 CPU 将内存源 ALU 指令解码为 2 个微指令,即加载和加法,它们在乱序后端分别执行。请参阅 Modern Microprocessors
A 90-Minute Guide!
了解构建更复杂 CPU 的温和介绍,包括现代 x86 解码到“类似 RISC”的微操作。
您可以构建与 Intel Sandybridge 系列非常相似的管道(请参阅 David Kanter 对 Haswell 前端和后端不同部分的框图的深入研究 - https://www.realworldtech.com/haswell-cpu/)或 AMD Zen,运行累加器 ISA 而不是 x86。
或者让它更简单一点,比如 P5 Pentium(按顺序双发出,无需解码为类似 RISC 的微指令,因此它也不能流水线化内存源 ALU 指令),或 486(按顺序流水线化单期)。
我怀疑有任何商业示例; AFAIK 没有纯累加器 ISA 足够相关,以至于任何人都想购买本质上低效 ISA 的高性能实现,而不是购买能够以相同的美元、功率、硅和设计成本更快地运行寄存器 ISA 的 CPU努力。
(即您可以这样做,或者您可以花费类似的精力来管道一个好的 ISA,如 ARM、MIPS 或 RISC-V。或者甚至像 m68k 这样更符合 CISC 的东西。)
不过,没有理由假设玩具微架构只有一个 MAR/MBR/IR。每条指令都需要自己的 IR 通过管道,假设它是一个具有固定宽度指令的 ISA,甚至有一个 IR 是有意义的,而不是基于解码结果的控制信号。
x86 registers: MBR/MDR and instruction registers 解释了为什么现实世界的 x86 CPU 不只有其中一个,而且根本没有“IR”。而且 MAR/MBR 对于流水线缓存访问来说太简单了,尤其是在具有虚拟内存的 CPU 上。