したがって、遅延スロットについての私の理解から、それらは分岐命令が呼び出され、分岐に続く次の命令もメモリからロードされるときに発生します。これのポイントは何ですか?分岐が行われた場合に、分岐後のコードが実行されないことを期待しませんか?分岐が行われない場合に時間を節約することですか?
パイプライン図を見ていると、とにかく分岐後の命令のようです。
最近のほとんどのプロセッサはパイプラインを使用しています。 H&Pブックのアイデアと問題はどこでも使用されています。これらのオリジナルの執筆時点では、実際のハードウェアはパイプラインの特定の概念と一致していたと思います。フェッチ、デコード、実行、書き戻し。
基本的に、パイプラインは4つのメインステージが含まれる組立ラインであるため、一度に作業できる指示は最大4つです。命令を実行するのに何クロックかかるかという概念を混同します。ましてそれは複数のクロックを必要としますが、いくつか/多くが並行して実行している場合、「平均」はクロックあたり1に近づくか超えることができます。
組立ラインは失敗しますが、ブランチを取るとき。フェッチおよびデコードステージの命令は破棄する必要があり、再び充填を開始する必要があるため、数クロックのヒットでフェッチ、デコードしてから実行に戻ります。ブランチシャドウまたは遅延スロットのアイデアは、これらのクロックの1つを回復することです。分岐後の命令が常に実行されることを宣言した場合、分岐が実行されると、デコードスロット内の命令も実行され、フェッチスロット内の命令が破棄され、2つではなく1つの時間の穴があります。したがって、execute、empty、empty、execute、executeの代わりに、パイプラインの実行ステージにexecute、execute、empty、execute、execute ...があります。ブランチの痛みが50%少なくなり、全体的な平均実行速度が向上します。
ARMには遅延スロットはありませんが、プログラムカウンターが2命令先であることを宣言することで、パイプラインのような錯覚を与えます。プログラムカウンターに依存するすべての操作(pc相対アドレッシング)は、2命令先のpcを使用してオフセットを計算する必要があります。ARM命令の場合、これは元のサム4バイトで8バイトです。あなたはthumb2の指示を追加すると、面倒になります。
これらは、現時点での学問の外の幻想であり、パイプラインはより深く、多くのトリックなどがあり、レガシーコードが機能し続けるため、および/またはアーキテクチャの変更ごとに命令の動作を再定義する必要がない(mips revを想像してください) x、1遅延スロット、rev y 2遅延スロット、rev z条件aの場合は3スロット、条件bの場合は2スロット、条件cの場合は1スロットc)プロセッサは先に進み、分岐後の最初の命令を実行し、もう一方を破棄しますそれがパイプを再び満たすとき、またはダース。パイプの実際の深さは、一般に公開されていないことがよくあります。
私はこれがRISCのものであるというコメントを見ました、それはそこから始まったかもしれませんが、CISCプロセッサは同じ正確なトリックを使用し、レガシー命令セットの錯覚を与えるだけで、時にはCISCプロセッサはRISCまたはVLIWコアにすぎませんレガシーCISC命令セットをエミュレートするラッパー(マイクロコード)。
その作り方をご覧ください。組立ラインを視覚化します。ラインの各ステップにはタスクがあります。ラインの1つのステップが青のwhatsitsを使い果たした場合、青と黄色の製品を作成するには、青のwhatsitsが必要です。そして、誰かが台無しにしたので、あなたは別の週のために新しい青いwhatsitsを得ることができません。したがって、ラインを停止し、供給を各ステージに変更して、しばらくの間赤と緑の製品を製造する必要があります。これは通常、ラインをダンプせずに適切に段階的に導入することができました。これは、アセンブリラインのどこかで分岐が発生した場合のように、何かが原因でラインを変更し、ラインをダンプする必要があります。遅延スロットは、1つの製品をラインで廃棄する必要がないように回復する方法です。ラインが停止する前にN個の製品が出てくる代わりに、生産工程ごとにN + 1個の製品が出ました。コードの実行は本番実行のバーストのようなもので、分岐をヒットして別の短い実行パスに移動したり、別の短い実行パスを分岐したりする前に、短い、時には長い線形実行パスを取得することがよくあります...
分岐が行われた場合に、分岐後のコードが実行されないことを期待しませんか?
しかし、もう手遅れです。 CPUパイプラインの目的は、すべてのサイクルで命令を完了することです。これを実現する唯一の方法は、サイクルごとに命令をフェッチすることです。したがって、分岐命令の後のコードはすでにフェッチされており、CPUが分岐を取る必要があることに気付く前に実行中です。
これのポイントは何ですか?
意味はありません。これは機能ではなく、単にこの種のパイプライン設計の成果物です。
RISCアーキテクチャの考え方は、デコードを簡素化し、パイプラインを最適化して速度を上げることです。 CPUはパイプライン化によって命令の実行をオーバーラップしようとするため、複数の命令が一度に実行されます。
遅延スロットのポイントは、具体的には、パイプラインの一部を介してすでに実行され、現在は捨てなければならないスロットにある命令を実行することです。
オプティマイザは、分岐ターゲットで最初の命令を受け取り、それを遅延スロットに移動して、「無料」で実行できます。
主に世界が既存のISAで標準化されたため、この機能は主流になりませんでした1 設計、つまりx86およびx86-64ですが、別の理由もあります。
トランジスタ数の2次爆発により、非常に高度なデコーダが可能になりました。アーキテクチャ上表示されているISAがいずれにせよマイクロオペレーションに変換されている場合、遅延スロットのような小さなハックは重要ではなくなります。
パイプライン実装の教科書の例では、CPU fetches、decodes、executes、およびwrites backです。これらのステージはすべて異なるクロックサイクルで発生するため、実際には各命令は4サイクルで完了します。ただし、最初のオペコードがデコードされようとしている間に、次のオペコードがメモリからロードされます。 CPUが完全に占有されている場合、同時に処理される4つの異なる命令の一部があり、CPUのスループットはクロックサイクルごとに1つの命令です。
マシンコードにシーケンスがある場合:
sub r0, #1
bne loop
xxx
プロセッサはwrite backステージのsub r0, #1
からexecuteステージのbne loop
まで情報をフィードバックできますが、同時にxxxはすでにステージfetch。パイプラインを展開する必要性を単純化するために、CPU設計者は代わりに遅延スロットを使用することを選択します。遅延スロット内の命令がフェッチされた後、フェッチユニットは分岐ターゲットの適切なアドレスを持っています。最適化コンパイラーはめったに遅延スロットにNOPを配置する必要はありませんが、可能な両方の分岐ターゲットで必ず必要な命令をそこに挿入します。