MIPS nop和sll的字节码是如何区分的?

问题描述 投票:0回答:1

据我所知,两条指令的操作码和功能码均为 0,那么计算机如何知道它在做什么?

assembly mips cpu-architecture instruction-set no-op
1个回答
2
投票

正如 Jester 所说,如果 MIPS CPU 不想做任何特殊的性能优化,Doesn't 必须区分。

sll $0, $0, 0
已经没有架构效果,因为写入
$0
被丢弃,并且它没有副作用(MIPS 没有标志/条件代码寄存器)。如此简单的硬件就可以让它通过管道运行。

有一个商定的

nop
操作码的要点是,如果硬件想要寻找一个特殊情况甚至不执行它,那么只有一个位模式必须匹配,而不是考虑每一个指令选择写入
$0
(可能仍然会出错的负载除外。)

因此编译器/汇编程序的开发人员不必猜测对于某些硬件来说什么

nop
可能是最便宜的。硬件可能做的事情包括:

  • 只有一个班次执行单元的超标量流水线可以在同一时钟周期内运行
    nop
    sll $t0, $t1, 12
    ,即使它通常不能在同一周期内运行两个班次。
  • 可能会因为不激活 ALU 而节省一些电量?
  • 可能根本不通过流水线发送NOP,只是在解码时丢弃它并获取下一条真正的指令。 (对于获取和解码的指令多于其流水线宽度的 CPU 来说是合理的,或者尤其是对于乱序执行 CPU。)
  • 如果风险检测还没有对
    $0
    上的每次读写进行特殊处理,则可以跳过
    nop
    。 (仅适用于没有旁路转发的玩具 CPU,见下文。)

甚至

sll $t0, $t0, 0
也没有架构效果,因为它用它已经拥有的相同值写入寄存器。但这是一个更糟糕的选择,因为危险检测通常会查看寄存器读写,因此它可能会导致停顿,或者
$t0
在像 R10000 这样的无序执行 MIPS 上的依赖链更长。但是,如果 MIPS 没有零寄存器,那么同意作为 NOP 将是一个合理的选择,除了在 MIPS 1 上将它放在写
$t0 的 loat 的加载延迟槽中是不安全的
.


对于根本没有尝试特殊情况

lw $0, (mem)
或零寄存器的硬件,是否存在带有
nop
/
nop
的任何可能的极端情况,零寄存器丢弃写入和读取作为零处理仅在注册文件?

在那种情况下,它会看到一条指令在下一条指令中读取加载结果。在 MIPS I 上,这会为读取的值提供不可预测的结果,因为它不会因旁路转发无法处理的危险而停止。 (在后来的 MIPS 上,它停止了;加载延迟槽不是体系结构的,只是性能的。)当然,结果最终只是写入零寄存器,所以没有明显的差异。

但是如果简单的硬件没有特殊情况下绕过转发的零寄存器,像

addiu $0, $0, 123
/
addi $1, $0, 0
这样的东西可以复制一个非零值。因此,正确的 MIPS 设计不可能那么简单,并且在为旁路转发进行危险检测时确实必须已经有特殊情况
$zero
,以确保它不会旁路转发到
$0
的读取,这是需要始终读零。

停止而不是旁路转发的 MIPS 设计不必在危险检测中特例

$0
,因为所有值都将通过寄存器文件。但这可能不是 MIPS 架构师的考虑因素,因为旁路转发对于大多数代码的良好性能至关重要。

© www.soinside.com 2019 - 2024. All rights reserved.