自作RISC-Vアウトオブオーダコアの実装、パフォーマンスの問題。分岐予測の効率が良くない。
特に今は非常にナイーブな実装であるため、JAL命令の予測ができていない。むしろこれは予測というよりも命令をキャッシュから取り出した時点で一発で分かるのでどうにかしたい。
問題はキャッシュからデータを取り出した後に1サイクルも明けずにJALの切り出しをしていることだ。絶対ここがクリティカルパスになってしまう。 本当は1サイクル開けた方がいいのだけれども、そうすると予測の時間が遅くなってしまう。この辺はBTBでバックアップできないかなあ...
あと問題になるのは、命令が16ビット境界を跨いで配置されている場合にどうやってJAL命令を認識するかということ。 例えば0x10eから0x113の4バイトにJAL命令が並んでいるとして、まずはキャッシュに0x100 - 0x10f`までをロードすると、とりあえずは下位のビットを見ることでJAL命令を認識することができる。
0x113 0x110 0x10e +-------+-------+ | JAL | +-------+-------+
0x10e-0x10fでJAL命令だということを認識してすぐにジャンプできるかというとそういうことではなく、オフセットの計算が要るので上位の16bitは必要だ。従って次の0x110から始まるキャッシュラインを読み込むまで待つ必要がある。
次のキャッシュラインが読み込まれるまで、下位の上位の0x10eがJAL命令であるということを一時的に覚えておいてもいいのだけれども途中でいろんなイベントが入ってその関係性が壊れると面倒くさくなりそうなので、上位の16bitはBTBに任せることにした。
つまり、過去のJAL命令で0x10eというキャッシュラインの境界に配置されているものは、BTBにその結果を記録して上位ビット(0x110)にフェッチが入るとJALだと予測するようにする。
これにより、とりあえずDhrystoneでJAL命令の予測率はほぼ100%に近づくようになった。 周波数についてはあまりチェックしていないけど、機能的にはこれで行くことにしよう。