使用NOP而不是stall有什么区别?在使用流水线的情况下,两者恰好执行相同的任务。我不明白
发布于 2015-11-04 13:07:31
我想你把你的术语搞混了。
处理器将停顿注入流水线中以解决数据风险(处理指令所需的数据尚不可用的情况。NOP
只是一条没有副作用的指令。
摊位
回想一下5个管道阶段classic RISC pipeline
考虑下面的代码片段:
add $t0, $t1, $t1
sub $t2, $t0, $t0
很明显,第二条指令依赖于第一条指令的结果。这是一个data hazard:写后读(RAW);一个真正的依赖。
sub
在其EX阶段需要add
的值,但add
仅处于其内存阶段-该值在WB阶段之前不可用:
+------------------------------+----+----+----+-----+----+---+---+---+---+
| | CPU Cycles |
+------------------------------+----+----+----+-----+----+---+---+---+---+
| Instruction | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
+------------------------------------------------------------------------+
| 0 | add $t0, $t1, $t1 | IF | ID | EX | MEM | WB | | | | |
| 1 | sub $t2, $t0, $t0 | | IF | ID | EX | | | | | |
+---------+--------------------+----+----+----+-----+----+---+---+---+---+
这个问题的One solution是处理器插入停顿或冒泡流水线,直到数据可用。
+------------------------------+----+----+----+-----+----+----+-----+---+----+
| | CPU Cycles |
+------------------------------+----+----+----+-----+----+----+-----+----+---+
| Instruction | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
+----------------------------------------------------------------------------+
| 0 | add $t0, $t1, $t1 | IF | ID | EX | MEM | WB | | | | |
| 1 | sub $t2, $t0, $t0 | | IF | ID | S | S | EX | MEM | WB | |
+----------+-------------------+----+----+----+-----+----+---+---+---+-------+
NOPs
NOP
是一条什么也不做的指令(没有副作用)。MIPS汇编程序通常支持nop
指令,但在MIPS this is equivalent to sll $zero $zero 0
中。
此指令将占用流水线的所有5个阶段。它最常用于填充跳转或分支的branch delay slot,此时该插槽中没有其他有用的操作。
j label
nop # nothing useful to put here
如果您使用的是MIPS模拟器,则可能需要启用分支延迟时隙模拟才能看到这一点。(例如,在spim
中使用-delayed_branches
参数)
发布于 2020-06-02 01:24:19
我们不应该用NOP代替摊位,反之亦然。
当存在导致危险的依赖时,我们将使用stall,这将导致流水线的特定阶段等待,直到它获得所需的数据,而通过使用NOP,在stall的情况下,它将只是通过指令的该阶段,而不做任何事情。然而,在使用NOP完成阶段之后,阶段所需的数据是可用的,我们需要从头开始执行指令,这将增加处理器的平均CPI,从而导致性能下降。此外,在某些情况下,该指令所需的数据可能会在重新启动该指令之前被另一条指令修改,这将导致错误执行。
同样,如果我们用摊位代替NOP的话。无论何时发生不可屏蔽的中断,比如在执行阶段(除以0),我们需要在不改变处理器状态的情况下通过异常之后的阶段。在这里,我们使用NOP来传递流水线的剩余阶段,而不改变处理器状态(比如向寄存器或内存中写入一些东西,这是异常产生的假值)。
这里,我们不能使用stall,因为下一条指令将等待stall完成,并且stall不会完成,因为它是一个不可屏蔽的中断(用户无法控制这些类型的指令),并且流水线进入死锁。
https://stackoverflow.com/questions/33071948
复制相似问题