1. 命令は5つの工程を通る — 流れ作業のしくみ
CPU は命令を IF(命令取得)→ ID(解読)→ EX(実行)→ MEM(メモリ)→ WB(書き戻し)の順で処理します。5つの工程はそれぞれ別の回路。だから1つの命令が EX にいる間、次の命令を IF に入れられます。
下のデモで ステップ実行してみてください。工程が埋まっていくと、やがて毎サイクル1つの命令が完成して出てきます。
5工程を流れる命令たち
色つきのタイルが命令。1サイクルごとに全員が1工程だけ右へ進みます。5サイクル目からは、5つの工程がすべて別々の命令で埋まり、右端から毎サイクル1命令が完成していきます。
POINT — 重ねるから速い
1命令に5工程かかっても、工程を1サイクルずつずらして重ねれば、パイプラインが満タンになった後は毎サイクル1命令が完成する。5つの回路を遊ばせず同時に働かせる、これがパイプラインの本質。
2. レイテンシとスループットは別物
ここで大事な区別。レイテンシは「1命令が入口から出口まで抜けるのにかかる時間」、スループットは「単位時間あたり何命令を仕上げられるか」。パイプラインが上げるのはスループットのほうです。
下で命令数を変え、チェックを外して順次実行(重ねない)と比べてみてください。最初の1命令が出てくるまでの時間は両方式で同じなのに、全体の所要時間はまるで違います。
空間×時間ダイアグラム — 重ねる vs 重ねない
横が時間(サイクル)、縦が命令。重ねると階段状に斜めへ流れ、5命令でも 命令数+4 サイクルで済みます。重ねないと1命令ごとに5サイクル待ち、命令数×5 サイクルに膨らみます。
スループット ≈ 1 命令 / サイクル (定常状態)
1命令あたりの平均サイクル = (命令数+4) / 命令数 → 命令数が増えるほど 1 に近づく。ただし最初の1命令のレイテンシは 5 サイクルのまま
注意 — よくある誤解
「パイプラインにすると1つ1つの命令が速くなる」は誤り。1命令が5工程を抜けるレイテンシは5サイクルのまま(むしろ工程を区切るぶん少し増えることも)。速くなるのは全体のスループットだけ。速さの正体は「1命令の短縮」ではなく「並行して重ねる」こと。
3. データハザード — 結果を待たされる
いいことばかりではありません。ある命令が、まだ書き戻されていない結果を使おうとすると、値が用意できるまで待たされます。これがデータハザード。待っている間、パイプラインには泡(バブル)という空白が挿入されます。
下の例で I2・I3 は I1 が計算した R1 を使います。フォワーディングのチェックを切り替えてみてください。素直に書き戻しを待つと泡が入り、EX の結果を直接横流しすると泡が消えます。
データハザードとフォワーディング
赤い「泡」が挿入されたストール。フォワーディングOFFでは、I1 の書き戻し(WB, 赤い矢印)を待って I2 の解読が遅れます。ONにすると、I1 の EX で出た結果を次の EX へ直接横流し(緑の矢印)するので、泡なしで流れます。
POINT — フォワーディングという抜け道
演算結果は EX の段階ですでに出ている。わざわざ WB でレジスタに書き戻されるのを待たず、EX の出口から次の命令の EX 入口へ直接配線で横流しすれば、多くのデータハザードは泡ゼロで解消できる。ハードウェアが依存を検出して自動でつなぐ。
一歩先へ — ロードユース・ハザード
フォワーディングでも消せない依存がある。ロード命令(メモリから読む)の結果は MEM 段が終わるまで出てこないので、直後の命令がその値を使うと最低1サイクルの泡が避けられない。コンパイラは、この隙間に無関係な命令を差し込む命令スケジューリングで泡を埋める。分岐命令が起こす制御ハザードには分岐予測で対抗する。
4. どれだけ速くなる? — 段数と高速化
工程を N 段に分け、M 個の命令を流すと、パイプラインでは N + M − 1 サイクル、重ねなければ N × M サイクル。命令をたくさん流すほど、高速化は段数 N に近づいて頭打ちになります。
段数・命令数と高速化の上限
上の2本のバーが総サイクル数の比較。下の曲線は、命令数 M を増やしたときの高速化。点線の上限(段数 N)に近づいていきます。ピンクの点が今の M の位置です。
高速化 = (N × M) / (N + M − 1) → N (M ≫ N のとき)
N = パイプラインの段数、M = 流す命令数。段数を増やせば理論上限は上がるが、段が深いほど分岐ミスの手戻りも大きくなる
5. まとめ — 流れ作業の光と影
- パイプライン:命令の工程をずらして重ね、全回路を同時に働かせる。定常状態のスループットは約1命令/サイクル。
- レイテンシ vs スループット:1命令の所要時間は変わらない。増えるのは単位時間あたりの完成数。
- ハザード:データ依存・分岐・資源競合で流れが乱れ、泡(ストール)が入る。フォワーディングや分岐予測で緩和する。
- 高速化の上限:命令をたくさん流すと段数 N に近づく。段を深くしすぎるとハザードの代償が増える。
一歩先へ — さらに欲張る現代CPU
1サイクルに1命令では飽き足らず、複数のパイプラインを並べて同時に発行するスーパースカラ、依存のない命令を追い越して実行するアウトオブオーダー実行、分岐先を予測して投機実行する仕組みまで積み重ねて、現代のCPUは1サイクルに数命令を仕上げる。すべては「回路を遊ばせない」という同じ発想の延長にある。