ちょっとCPU設計のフロントエンドについて勉強がしたくなって、プリフェッチに関する論文を読むことにした。
前回の続き。分岐予測器の基本的なところからサマライズしておく。
第2章:基本情報
A. 分岐予測について
そもそも分岐予測の目的は、分岐命令に遭遇した際に分岐先を正しく予測することによりパイプラインをストールさせることなくコアの性能を維持することである。
現代のプロセッサには、分岐命令の特徴に応じて様々な分岐予測器が搭載されている:
- 分岐方向予測(そもそも分岐が成立するかしないか)
- Saturationカウンタによって過去の分岐結果に基づき同じ分岐命令が次に分岐成立するかどうかを予測する。
- 分岐ターゲット (Branch Target Bufferのことを指している?)
- ループ検出
- リターンアドレススタック (Return Address Stack)
間接分岐、つまりレジスタ値を参照して分岐先を決定する分岐命令の場合には、専用の間接分岐予測器を使うことができる。
関数から戻るReturn命令の予測には、関数呼び出し時にプッシュしたReturn Address Stackを使用して、RASの先頭アドレスをReturn命令のジャンプ先として使用できる。
ループ予測器は、ループの反復回数でループを特定する。
分岐予測の結果を正確に記録することが、次の分岐に役立てるために非常に重要であり、これらの分岐予測結果は、グローバル履歴レジスタ(Global History Register: GHR)に保存される。
分岐履歴の記録 = 分岐方向履歴 << 1 | 分岐命令結果 ターゲットハッシュ = (命令アドレス >> 2) XOR (ジャンプターゲット >> 3) ターゲット履歴 = (ターゲット履歴 << 2) XOR ターゲットハッシュ
予測自体にレイテンシがかかってしまうことにより、ストールが生じることを避けるために、分岐予測自体は、フェッチステージで行われる。
命令タイプは特定されないが、BTBに残っている分岐命令の履歴から、次のジャンプターゲットを予測することができる。
商用プロセッサは分岐予測器のサイズを大きくする傾向にあり、これによるレイテンシの増加を抑えバンド幅を維持するために、シングルポートSRAMを利用したり、マルチポートSRAMやマルチバンク構成を取ることがある。また、複数レベルのBTB階層を実装することもできる。
B. Fetch Directed Prefetch
FDP(Fetch Directed Prefetch)というのは、分岐予測機構を利用して命令プリフェッチを開始するためのもの。
プリフェッチというのは、命令ジャンプ先に応じてフェッチを行う本物とフェッチと違い、あらかじめ使われるであろうキャッシュブロックを取り込むためのフェッチのこと。
分岐予測器により、未来に使用されるフェッチアドレスを予測し続け、それをFTQ(Fetch Target Queue)というキューに投入する。FTQに格納されたものから一つ取り出してBTBにアクセスし、次の命令フェッチアドレスを生成する。
取り出したBTBの中に分岐命令が含まれている場合、方向分岐予測器から供給されるジャンプ方向によって分岐先を決定する。
これによりFDPは効率的にプリフェッチを実現することができるが、その精度はBTBの容量に大きく依存する。BTBで分岐が検出されないと誤った方向のプリフェッチを出してしまう可能性がある。さらにBTBに正しく情報が格納されていないと、不正確なプリフェッチにつながる可能性がある。