RISC-V のベクトル命令の仕様一覧のページ
サイクル精度シミュレータ Sniperの勉強
- AMBA CHIについての勉強
- オープンソース形式検証ツールSymbiYosysを用いて形式検証に入門する
- Vivado Simulatorを使ってUVMに入門する
- RISC-V IOMMU の構成についてマニュアルを読んでまとめる
RISC-V のベクトル命令の仕様一覧のページ
サイクル精度シミュレータ Sniperの勉強
XiangShan の aBTB (Ahead-BTB) は、公開スライドを見る限り、BP1/S1 段に置かれた大容量の先行BTBである。BPU全体は3-stage prediction pipelineで構成される。
が置かれている。つまり aBTB は、精密な最終判定器というより、フロントエンド初段で先読みして fetch を止めないための predictor である。
容量は 1K entries / 4-way と明示されている。

https://tutorial.xiangshan.cc/micro25/slides/Microarchitecture Design Philosophy.pdf

この構成から読めるのは、BP1 はレイテンシ最優先、BP3 は精度優先 という役割分担である。aBTB は BP1 側にいるので、「分岐を厳密に解く」より “次にどこを取りに行くべきかを先に出す” のが主目的となる。
| Predictor | Index | Tag | 予測 |
|---|---|---|---|
| uBTB (left) | A | A | B |
| aBTB (right) | A | B | C |

現在フェッチしている A で引く index = A tag = A pred = B A を見た瞬間に「A の中の最初の taken branch の飛び先は B」を返す

現在フェッチしている A で引く index = A ただし tag = B pred = C A の時点で「次に来るはずの B が正しいなら、 その次の有力候補は C」を返す
通常のBTBなら、「今見ているブロックのPC」 で引いて、「そのブロック内の分岐ターゲット」 を返せばよい。ところが aBTB は 将来のフェッチブロック C を先に返したい。すると A だけでは情報が足りない。そこで、
という構成になりなる。
+------------------------------+ | set/index key : A | | tag : B | | payload : C address | +------------------------------+
つまり aBTB は、単一ブロックに対するターゲット表 ではなく、フェッチブロック列 A→B→C の相関を圧縮して持つ表 となる。これは classic な ahead predictor の考え方そのものですが、XiangShan の公開資料ではそれを BP1 の S1 predictor として実用的に組み込んでいる。
前回の続き:msyksphinz.hatenablog.com
TAGEの実装(gem5)を読むと、FoldedHistory がテーブル数ぶん存在し、さらに tag 用が2本ある。
GHRは1本のビット列だが、テーブル $T_i$ はそれぞれ異なる履歴長 $L_i$ を参照する。したがって
fold(GHR, L1) と fold(GHR, L2) は別物であり、テーブルごとに圧縮履歴を持つのは自然である。
C++モデルであっても、分岐予測は非常に高頻度で呼ばれる。毎回 GHR の長いビット列を走査して fold を計算するとコストが高い。そこで gem5 は
という構成を取る(スループット重視)。
gem5のタグ生成(gtag())は次の形を取る(メモの通り)。
tag = (pc>>instShiftAmt) ^comp0 ^ (comp1<<1); tag&= (1<<tagWidth)-1;
ここで comp0 = computeTags[0][i].comp、comp1 = computeTags[1][i].comp は、同じGHR窓を
で折り畳んだ2種類の指紋である。
idx衝突は不可避なので、tagの役割は「同じidxに来た別文脈を弾く」ことになる。しかし長履歴を短い tag 幅に圧縮すると偏りが出やすく、tag衝突(偽ヒット)が増える。そこで、2種類の折り畳みを混ぜて tag を“ハッシュ的”にし、偽ヒットを減らす。
前回の続き:msyksphinz.hatenablog.com
更新則に入る前に、まず「予測時に何が起きているか」を整理する。これは TAGE の理解に必須である。
各テーブル $T_i$ は履歴長 $L_i$ を持つ(幾何級数)。まず履歴を固定幅に圧縮し、PCと混ぜて index と tag を作る。
圧縮履歴(fold)は、長い履歴をそのまま利用できないための実装上の工夫である。
テーブル $T_i$ から idx_i のエントリを読み出し、タグ一致を確認する。
Ti[idx_i] -> {stored_tag, pred_ctr, u}stored_tag == tag_iヒットしたテーブルは「このPC+履歴文脈に対応するエントリが存在する」と解釈される。
TAGEの合成の要点は “選択” である。
予測は原則 provider の pred_ctr で決めるが、実用実装では provider が弱い場合や新規割当直後などに alternate を選ぶ規則を持つことがある。ここが更新則の設計と密接に結びつく。
前回の続き:msyksphinz.hatenablog.com
ここでは、三者の関係を「同じ粒度の図」で並べ、差分を固定する。



要点は一行で言える。
分岐予測器は、短い履歴相関(直近の局所性)と長い履歴相関(長距離依存)を同時に扱う必要がある。この要請は自然に「複数コンポーネント(複数テーブル)を持つ予測器」を導くが、そこで重要になるのがコンポーネント出力の合成(combining function)である。
GEHL / O-GEHL 系は、履歴長の異なる複数テーブルが出力する 符号付きカウンタ値(スコア)を加算し、合計の符号で taken/not-taken を決める。加算を高速に行うため、加算器を木構造に組む(adder tree)。
ci(signed counter)を返すこの合成は「重み付き投票」に相当し、履歴長ごとの寄与を統合できる一方、毎予測で複数テーブル参照と加算が必要になる。
O-GEHLは、履歴長を幾何級数(geometric series)で配置する。短い履歴のテーブルに容量を割きつつ、長い履歴相関も取り込めるため、限られたストレージ予算で精度を引き上げる設計になっている。
TAGE(TAgged GEometric history length)は、幾何級数履歴長という設計観は共有しつつ、合成関数を「加算」ではなく タグ付きテーブルのヒット/ミスによる“選択”へ置き換える。
この枠組みは “PPM-like(最長一致を選択)” と呼ばれる系統に属する。TAGEの論文は、従来PPM-likeタグ予測器の弱点を 更新(update policy)に求め、更新・割当(allocation)を再設計することを重要な貢献としている。
前回の続き:
上のジレンマ(timeliness↔汚染、しかもoff-pathは一概に捨てられない)を崩すために、UDP論文は2つの解決方法を提案している。
UFTQが「どれだけ先読みするか(FTQ深さ)」を調整するのに対し、UDPは prefetch candidate(候補)単位で“出す/捨てる”を学習して、特に off-pathでのunuseful(汚染)を削る。
基本方針はシンプルで、
- on-path:最終的に「正しかった」制御フロー(正解経路)上でフェッチ/実行される命令・フェッチブロック
- off-path:分岐予測が外れた結果として一時的にフェッチされる「間違った」制御フロー(誤予測経路)上の命令・フェッチブロック