Mips32 在MIPS中使用NOP和STALL有什么区别
使用NOP而不是stall有什么区别。Mips32 在MIPS中使用NOP和STALL有什么区别,mips32,Mips32,使用NOP而不是stall有什么区别。 在使用管道的情况下,两者恰好执行相同的任务。我听不懂我想你把术语弄糊涂了 处理器将暂停注入管道以解决数据危害(处理指令所需的数据尚不可用的情况)。NOP只是一条没有副作用的指令 中庭 回顾5个管道阶段: IF-指令获取(从内存中获取下一条指令) ID-指令解码(找出这是哪条指令以及操作数是什么) EX-Execute(执行操作) MEM-内存访问(存储或从内存读取) WB-写回(将结果写回寄存器) 考虑代码片段: add $t0, $t1, $t1 su
在使用管道的情况下,两者恰好执行相同的任务。我听不懂我想你把术语弄糊涂了 处理器将暂停注入管道以解决数据危害(处理指令所需的数据尚不可用的情况)。NOP只是一条没有副作用的指令
中庭 回顾5个管道阶段:
add $t0, $t1, $t1
sub $t2, $t0, $t0
从这里可以明显看出,第二条指令依赖于第一条指令的结果。这是一个:先读后写(RAW);一个真正的依赖关系
sub
在其EX阶段需要add
的值,但add
仅在其MEM阶段-在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 | | | | | |
+---------+--------------------+----+----+----+-----+----+---+---+---+---+
解决这个问题的方法是处理器插入暂停或冒泡管道,直到数据可用
+------------------------------+----+----+----+-----+----+----+-----+---+----+
| | 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 | |
+----------+-------------------+----+----+----+-----+----+---+---+---+-------+
不
NOP
是一条不做任何事情(没有副作用)的指令。MIPS汇编程序通常支持NOP
指令,但在sll$zero$zero
中
此指令将占用管道的所有5个阶段。当无法在该插槽中执行任何其他有用操作时,它最常用于填充跳转或分支
j label
nop # nothing useful to put here
如果您使用的是MIPS模拟器,您可能需要启用分支延迟时隙模拟才能看到这一点。(例如,在
spim
中使用-delayed\u branchs
参数)我们不应使用NOP代替暂停,反之亦然
当存在导致危害的依赖关系时,我们将使用暂停,这导致管道的特定阶段等待,直到它获得所需的数据,而在暂停的情况下使用NOP,它将只通过指令的该阶段而不做任何事情。然而,在使用NOP完成该阶段后,t阶段可用,我们需要从头开始指令,这将增加处理器的平均CPI,导致性能降低。此外,在某些情况下,该指令所需的数据可能会在重新启动指令之前被另一条指令修改,从而导致错误执行
同样的,如果我们用摊位代替NOP。
每当在执行阶段出现不可屏蔽的中断(被零除)时,我们需要在异常后传递这些阶段,而不改变处理器的状态。在这里,我们使用NOP传递管道的其余阶段,而不改变处理器的状态(比如将某个值写入寄存器或内存,这是异常生成的假值)
在这里,我们不能使用暂停,因为下一条指令将等待暂停完成,而暂停将不会完成,因为这是一个不可屏蔽的中断(用户无法控制这些类型的指令),并且管道进入死锁。回答此问题的大脑是否会尝试回答我的第二个问题:(一般地)NOP是否暗示上下文无关。那么NOP是否会导致上下文更改?同样,stall暗示上下文是否与我相关?不。上下文是操作系统级别的。我们谈论的是微体系结构。公认的答案非常好,但我想补充/澄清的一点是,因为每个
NOP
指令占用所有5个阶段,增加1个两条相关指令之间的nop
指令实际上会将第二条指令延迟一个周期。因此,如果您使用上面的示例中的add
和sub
,您会在两条nop
指令之间放置两条在这两种情况下,inst0
之后的每一条指令都将延迟2个CPU周期,所以为什么不让它暂停,等待危险消除,而不是使用NOP
,它只是在管道中插入一个间隙,什么也不做。我仍然感到困惑。示例是分支延迟槽。ISA定义了我必须在那里放一个指令,所以如果你没有什么你想做的,那么你应该用一个什么都不做的指令来填充它。