ストールの代わりにNOPを使用するとどのような違いがありますか。パイプライン化の場合、どちらもたまたま同じタスクを実行します。理解できない
用語が混乱していると思います。
データハザード(命令の処理に必要なデータがまだ利用できない状況。NOP
は副作用のない単なる命令です)を解決するために、プロセッサによってストールがパイプラインに注入されます。
5パイプラインステージを思い出してください クラシックRISCパイプライン :
コードスニペットについて考えてみましょう。
add $t0, $t1, $t1
sub $t2, $t0, $t0
ここから、2番目の命令が最初の命令の結果に依存していることは明らかです。これは データハザード :書き込み後の読み取り(RAW); a真の依存関係。
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 | | | | | |
+---------+--------------------+----+----+----+-----+----+---+---+---+---+
1つの解決策 この問題の解決策は、データが利用可能になるまで、プロセッサがストールまたはバブルパイプラインストールを挿入することです。
+------------------------------+----+----+----+-----+----+----+-----+---+----+
| | 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
命令をサポートしますが、 MIPSではこれはsll $zero $zero 0
と同等です。
この命令は、パイプラインの5つのステージすべてを使用します。最も一般的には、ジャンプまたはブランチの ブランチ遅延スロット を埋めるために使用されますが、そのスロットで実行できる有用なものは他にありません。
j label
nop # nothing useful to put here
MIPSシミュレーターを使用している場合、これを確認するには、分岐遅延スロットシミュレーションを有効にする必要があります。 (たとえば、spim
では-delayed_branches
引数を使用します)