流水线图,如果前面的EX使用相同的寄存器,ID可以启动吗?

Pipeline diagram, Can ID start if previous EX is using same register?

我最近开始使用计算机 architecture.I 对我试图整理的图表感到困惑。基于依赖关系并努力避免危险,我设计了以下 table。但是我不确定 2 个阶段是否可以同时从同一个寄存器读取。这里 table 和突出显示混淆区域的 mip。

编辑:添加了备选方案

移除一个摊位是否正确,因为 r0 的值已经被处理?

"Using" 太笼统了,您需要在对寄存器的读取和写入之间进行拆分。 如果您询问 "reading at the same time" - 当然,这就是流水线的重点。只要寄存器值不变,反复读取是没有问题的。 实际上,ID 阶段和 EX 阶段没有使用相同的资源,因此没有冲突 - EX 阶段读取的值来自 ID 阶段在上一个周期中写入的锁存器。

您认为是单个全局值的寄存器实际上在管道上有多个副本,每个副本都对应于程序中某个点的值。如果您采用最后 2 条指令,例如,都读取 $r0,那么 ID 阶段将在第 7 个周期从寄存器文件中读取它以进行 OR,将其写入锁存器,然后在第 8 个周期再次读取它以进行 XOR ,而 OR 处于 EX 阶段,同时取前一个周期的锁存值。

现在,真正的问题出现在您遇到数据冒险时,例如由第一条指令引起的问题。由于寄存器在任何给定阶段的值必须反映它根据程序顺序所具有的真实值,如果您尝试在周期 2 上为 Sub 指令执行 EX 阶段,就会遇到问题,因为 $r0 值是在上一个循环而不代表 Add 的结果。事实上,只有在 Add 在周期 4 完成回写后,该值才会在寄存器文件中准备就绪。这称为 RAW(先写后读)冲突,必须修复,否则程序将产生虚假结果。解决这个问题的一种方法是在检测到这种危险后添加一个停顿(如图中带星号的部分所示)——当读取 $r0 的指令最终继续时,它们将具有已经写入的更新值(post 添加)到闩锁。另一个(更有用的)解决方案是添加特殊逻辑,以便在新值准备就绪后绕过所有需要它的管道阶段。在这种情况下,这可能仍然需要暂停,因为指令是背靠背的,因此您甚至没有时间在下一条指令需要它之前执行该操作。

最后一点 - 请记住处理器,即使是像流水线 mips 这样简单的处理器,也会对您撒谎。它们让你相信你是 运行 你编写的程序,而实际上它们在不告诉你的情况下在内部做各种事情(一个稍微高级的例子是乱序执行)。在这种情况下,它们会让您认为指令是连续执行的,而实际上它们是在前一个指令完成(甚至执行)之前推测性地开始每一个指令。这当然在大多数情况下都有效,并使处理器在指令吞吐量(或 IPC)方面表现得更好,但在某些情况下(数据危害,如此类,控制危害等),这可能会完全破坏您的程序,所以他们必须通过添加摊位或冲洗管道等方式来隐藏这一点。