Architecture 管道图,如果前一个EX使用相同的寄存器,ID可以启动吗?

Architecture 管道图,如果前一个EX使用相同的寄存器,ID可以启动吗?,architecture,mips,pipeline,computer-architecture,Architecture,Mips,Pipeline,Computer Architecture,我最近刚开始学习计算机体系结构。我对我正在整理的一个图表感到困惑。基于依赖关系,为了避免危险,我设计了下表。但是,我不确定两个阶段是否可以同时从同一寄存器读取数据。这里是带有突出显示的混淆区域的表格和mips 编辑:添加备选方案 由于r0的值已被处理,删除一个暂停是否正确 “使用”过于笼统,您需要在寄存器的读写之间进行拆分。 如果你问起“同时阅读”——当然,这就是流水线的全部意义。只要寄存器值没有改变,反复读取就没有问题。 实际上,ID和EX stage并没有使用相同的资源,因此没有冲突——EX

我最近刚开始学习计算机体系结构。我对我正在整理的一个图表感到困惑。基于依赖关系,为了避免危险,我设计了下表。但是,我不确定两个阶段是否可以同时从同一寄存器读取数据。这里是带有突出显示的混淆区域的表格和mips

编辑:添加备选方案

由于r0的值已被处理,删除一个暂停是否正确

“使用”过于笼统,您需要在寄存器的读写之间进行拆分。 如果你问起“同时阅读”——当然,这就是流水线的全部意义。只要寄存器值没有改变,反复读取就没有问题。 实际上,ID和EX stage并没有使用相同的资源,因此没有冲突——EX stage读取的值来自ID stage在上一个周期中写入的锁存器

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

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


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

你在哪本教科书/参考书上学习?我还想做计算机架构的修订。亚马逊的任何链接都会有所帮助。提前谢谢…我用了几本书作为基础。如果我理解正确的话,r0的值已经被处理并在锁存器中,那么替代值是否正确?@eneko,你是说写入的新值?从按程序顺序写入的角度来看,它是正确的,即任何较年轻的指令在读取$r0时都应该使用它。这就好像CPU将指令序列化,这样每个指令都可以“原子地”从头到尾执行,而不需要任何交错。我是指我添加到问题中的新表。哦,只有添加一些旁路才可以(例如,周期4中的写入阶段将在周期5绕过EX,因此EX将能够选择$r0的新值,而不是ID阶段获得的旧值。这需要一些能够匹配寄存器名称的逻辑(仅当存在匹配时才希望绕过),但这是经常做的事情。如果我想计算此指令集的每条指令的周期,该怎么办?我可以看出其中5条是R型的,我应该使用通用公式吗?我不知道如何使用它@Leeor