MIPS 中分支指令的 NOPS 数
Number of NOPS for a branch instruction in MIPS
我们最近在谈论单周期和流水线处理器时讨论了电路中的 NOP class。如果我们有如下代码:
add $t1, $t2, $t3
sub $t4, $t1, $t0
由于 $t1
,存在数据危险。在没有数据冒险检测单元的流水线处理器中,在 $t1
的更新值被写回寄存器之前,sub 指令使用旧值 - 因此存在数据冒险。如果我们添加 2 个 NOPS 那么我们就可以解决这个问题,或者,如果有数据危险检测单元,我们可以在执行阶段之后转发结果 fo $t1
。
但是如果我们有一个分支指令呢?例如:
add $t1, $t2, $t3
beq $t0, $t1, Label
如果我们不能使用转发,我们是否也在这里添加 2 个 NOPS?
在没有分支预测的标准流水线MIPS处理器中,beq
的相等性测试是在ALU中进行的,即在EX阶段——这意味着它受制于相同的ALU -> ALU危险和相同的旁路将减轻这种危险。
(这与分支指令之后可能发生的流水线重新填充停顿无关,来自采用或错误预测的分支,但只是针对您显示的数据依赖性的延迟。)
如果理论处理器是流水线但没有危险保护(旁路或延迟),则需要与第一个场景相同的 2 个 nop。
如果没有额外的架构细节,很难做出明确的回答。并且有这么多版本的 mips 架构。
但是先看看你的声明
add $t1, $t2, $t3
sub $t4, $t1, $t0
There is a data hazard because of the $t1...
对
If we add 2 NOPS then we can solve this issue
不是真的。没有任何数据转发意味着,通过一个 NOP,新的 $t1 将在 MM/WR 管道寄存器中,并且通过第二个 NOP,它将被写回寄存器组。但不是 DI/EX 管道注册。因此,为了仅通过两个 NOPS 获得正确的行为,您需要一种方法将写回寄存器组的数据转发到 DI/EX 寄存器,或者使用诸如在寄存器组的时钟下降沿写入等技巧并在周期的第二部分阅读它。
我们假设您的假设是正确的,并且在寄存器组的输入和输出之间存在某种转发。
关于分支指令,有几种实现方式。
最明显的方法是使用EX阶段用ALU同时计算条件($t0=?$t1)和用附加加法器计算分支地址。但是它有一个主要的缺点:当这个计算完成时,LI 阶段正在获取一条新指令(并且一个已经在解码阶段),这会导致 2 个周期的分支惩罚。
经典mips流水线所做的是在解码阶段处理分支。加法器在这个阶段用PC+立即数计算分支地址,并添加了一个专用比较器来直接比较寄存器组的输出(顺便说一句,这就是分支指令只能比较eq/neq的原因,为了简化这个比较器,而ALU比较器可以做其他种类的比较)。这样,分支惩罚只有一个周期。
如果我们假设这是您的实际架构,并且我们没有转发手段,除了寄存器组,那么一个 NOP 就足够了。在一个 NOP 之后,新的
$t1 的值在 MEM/WR 管道规则中。并在下一个周期前半个周期回写到寄存器组,可用于后半个周期的分支比较。
当然,如果你假设分支是在EX阶段处理的(并且你有2个周期的分支惩罚),那么需要第二个NOP。
我们最近在谈论单周期和流水线处理器时讨论了电路中的 NOP class。如果我们有如下代码:
add $t1, $t2, $t3
sub $t4, $t1, $t0
由于 $t1
,存在数据危险。在没有数据冒险检测单元的流水线处理器中,在 $t1
的更新值被写回寄存器之前,sub 指令使用旧值 - 因此存在数据冒险。如果我们添加 2 个 NOPS 那么我们就可以解决这个问题,或者,如果有数据危险检测单元,我们可以在执行阶段之后转发结果 fo $t1
。
但是如果我们有一个分支指令呢?例如:
add $t1, $t2, $t3
beq $t0, $t1, Label
如果我们不能使用转发,我们是否也在这里添加 2 个 NOPS?
在没有分支预测的标准流水线MIPS处理器中,beq
的相等性测试是在ALU中进行的,即在EX阶段——这意味着它受制于相同的ALU -> ALU危险和相同的旁路将减轻这种危险。
(这与分支指令之后可能发生的流水线重新填充停顿无关,来自采用或错误预测的分支,但只是针对您显示的数据依赖性的延迟。)
如果理论处理器是流水线但没有危险保护(旁路或延迟),则需要与第一个场景相同的 2 个 nop。
如果没有额外的架构细节,很难做出明确的回答。并且有这么多版本的 mips 架构。
但是先看看你的声明
add $t1, $t2, $t3
sub $t4, $t1, $t0
There is a data hazard because of the $t1...
对
If we add 2 NOPS then we can solve this issue
不是真的。没有任何数据转发意味着,通过一个 NOP,新的 $t1 将在 MM/WR 管道寄存器中,并且通过第二个 NOP,它将被写回寄存器组。但不是 DI/EX 管道注册。因此,为了仅通过两个 NOPS 获得正确的行为,您需要一种方法将写回寄存器组的数据转发到 DI/EX 寄存器,或者使用诸如在寄存器组的时钟下降沿写入等技巧并在周期的第二部分阅读它。
我们假设您的假设是正确的,并且在寄存器组的输入和输出之间存在某种转发。
关于分支指令,有几种实现方式。
最明显的方法是使用EX阶段用ALU同时计算条件($t0=?$t1)和用附加加法器计算分支地址。但是它有一个主要的缺点:当这个计算完成时,LI 阶段正在获取一条新指令(并且一个已经在解码阶段),这会导致 2 个周期的分支惩罚。
经典mips流水线所做的是在解码阶段处理分支。加法器在这个阶段用PC+立即数计算分支地址,并添加了一个专用比较器来直接比较寄存器组的输出(顺便说一句,这就是分支指令只能比较eq/neq的原因,为了简化这个比较器,而ALU比较器可以做其他种类的比较)。这样,分支惩罚只有一个周期。
如果我们假设这是您的实际架构,并且我们没有转发手段,除了寄存器组,那么一个 NOP 就足够了。在一个 NOP 之后,新的 $t1 的值在 MEM/WR 管道规则中。并在下一个周期前半个周期回写到寄存器组,可用于后半个周期的分支比较。
当然,如果你假设分支是在EX阶段处理的(并且你有2个周期的分支惩罚),那么需要第二个NOP。