操作して学ぶ

CPUパイプライン可視化

5段パイプライン(IF/ID/EX/MEM/WB)に命令列を流し、後続の命令が先行の結果をいつ必要とするかで ストールが発生する様子を可視化します。フォワーディングを切ると依存が牙を剥き、 入れてもロードだけは1サイクル逃げ切れないのが分かります。 分岐命令では「常に停止」「不成立を予測」「成立を予測」を切り替え、予測が外れたときのフラッシュも確認できます。

subがaddの結果r1を直後で読む。フォワーディングが無いと2サイクル停止、あれば0サイクル。

フォワーディング

総サイクル

8

理想(n+4)

8

ストール/フラッシュ

0 / 0

CPI

2.00

CPI = 総サイクル ÷ 命令数。ストールが無くても、短い命令列では立ち上がり4サイクル分の影響でCPIは1に届かない(命令数が増えるほど1に近づく)。

命令12345678
add r1, r2, r3
IF
sub r4, r1, r5
and r6, r7, r8
or r9, r10, r11
状態

SストールFフラッシュHフェッチ保留

サイクル 1 / 8

c1: IF=add r1, r2, r3

レジスタは前半で書き後半で読む慣行のため、WB段と同サイクルの読み出しは安全(ハザードにならない)。 フォワーディングはEX段・MEM段の結果を演算器入力へ直接送るが、ロードの結果はMEM段が終わるまで存在しないため、 直後の命令がEXで使おうとする「ロード・ユース」だけはフォワーディングがあっても1サイクル止まる。

なぜロード・ユースだけ特別か

フォワーディングは「もう計算済みの結果」を演算器の入力へ直接配線で送るだけで、存在しない結果は前倒しできません。 ALU命令の結果はEX段の出口で確定しているので、次の命令のEX段へそのまま転送できます(0ストール)。 ですがロード命令の結果はMEM段が終わるまで確定しません。直後の命令がEX段で使おうとするタイミングにはまだ間に合わないため、 フォワーディングがあっても1サイクルだけ待つ必要があります。

依存の形フォワーディング無しフォワーディング有り
ALU → ALU(隣接)2ストール0ストール
LW → ALU(隣接、load-use)2ストール1ストール
ALU/LW → ALU(1命令挟む)1ストール0ストール

レジスタファイルは前半サイクルで書き、後半サイクルで読む慣行を前提にしています(多くの教科書の標準的な仮定)。

分岐ペナルティも「解決の早さ」で決まる

この可視化では分岐がEX段の末尾で解決すると仮定しているため、影響を受ける投機フェッチは2命令ぶんです。 「常に停止」は的中/外れに関わらず必ず2サイクル損しますが、「不成立を予測」は外れたときだけ2サイクルのフラッシュが発生し、 当たれば0サイクルで通過します。実機の分岐予測器が的中率にこだわる理由はここにあります。