パイプラインが滞り性能が落ちる要因(データ・制御・構造の3種)
パイプラインハザードとは、パイプライン(命令を流れ作業で重ねて実行する仕組み)が、何らかの理由で順調に流せなくなり、待ち時間が発生する状態のことです。
身近な例で考えると、工場のベルトコンベアで部品が1つ届かず、作業者全員が手を止めて待っている状態に似ています。この「何もできずに待つ空のクロック」をストール(または「バブル」=泡)と呼びます。1か所詰まると後続もずれて全体が遅れるため、せっかくのパイプラインの高速化効果が薄れてしまいます。
上のツールで▶ボタンを押すと、赤い破線の「待ち」マスが挿入され、その後の命令が遅れていく様子が見られます。シナリオを切り替えると、データ・制御・構造の3種類のハザードを順に確認できます。
ハザードは原因によって次の3種類に分類されます。この3分類はしっかり押さえておきましょう。
・データハザード:前の命令の計算結果を、次の命令がまだ使えない(結果待ち)
・制御ハザード(分岐ハザード):分岐命令の行き先が確定するまで、次にどの命令を読むか決まらない
・構造ハザード:同じ装置(メモリなど)を複数の命令が同時に使おうとして競合する
データハザードの典型例が、ツールの「データハザード」シナリオです。ADD R3,R1,R2 が R3 に結果を書く前に、後続の SUB R5,R3,R4 が R3 を使おうとするため、結果が書き終わるまで待つしかありません。料理で「ソースができる前に盛り付けようとして手が止まる」イメージです。
制御ハザードは分岐命令(if文のような条件分岐)で起きます。「どっちに進むか」が決まるまで次の命令を読み込めません。構造ハザードは、ある命令のメモリアクセス(MEM)と別の命令の命令フェッチ(IF)が同じメモリを取り合う、といった資源の競合で起きます。
ハザードによるストールを減らすため、CPUやコンパイラはさまざまな工夫をしています。
| ハザード | 主な対策 | 考え方 |
|---|---|---|
| データ | フォワーディング(バイパス) | WB前の結果を直接次の命令へ横流し |
| データ | 命令スケジューリング | 依存しない命令を間に並べ替える |
| 制御 | 分岐予測 | 分岐先を予測して先に読み込む |
| 制御 | 遅延分岐 | 分岐の直後に意味のある命令を置く |
| 構造 | 資源の分離・多重化 | 命令用とデータ用にメモリを分ける |
特に重要なのがフォワーディング(バイパス)です。これは、計算結果がレジスタに書き戻される(WB)のを待たず、EXで出た結果をすぐ次の命令へ横流しする仕組みです。料理で言えば「鍋からソースを直接お皿にかける(瓶詰めを待たない)」ようなもので、データハザードのストールを大幅に減らせます。
整理のポイント:「ハザードの3分類とその原因」「ストール=バブル」「データハザードの対策=フォワーディング、制御ハザードの対策=分岐予測」をセットで理解しておくとよいでしょう。ツールで各ハザードに何クロックのストールが入るかを実際に数えると、性能低下のイメージが掴めます。