自作RISC-VプロセッサにRAS(Return Address Stack)を実装して性能を調査した。
RASの実装をここしばらくやっていたのだが、意外と難しいということが分かった。
Return命令の判定をどこで行うか
RAS以外の分岐予測、アドレスを使って分岐予測を行う方式の分岐予測は、フェッチアドレスを見て予測し、次のフェッチアドレスを決める。 この方式の場合はIFU(命令フェッチユニット)から出力されるアドレスを見ればよいのだが、RASの場合はReturn命令を検出しなければならないので、 フェッチ後のデータを見て予測しなければならない。したがって、予測がアドレスを基にする予測よりも少し遅れることになった。
よって、アドレスを使う分岐予測BHTなどと比較して少しペナルティが発生することになった。これについては、まあそんなものだということで割り切らなければならない。
Return予測の失敗条件
RAS予測の失敗条件というのはいろいろあって、思いついたのは、
- Return Registerが書き換えられていて、予測したは良いが実際のアドレスが異なっていた。
- ジャンプの深さが深すぎて、昔のジャンプ記録が破棄されてしまった(今回の実装では最大深さ4のJump And Link命令しかサポートしていない)。
などがありうる。したがって、RASは無条件分岐命令だけれども、本当に正しいアドレスに分岐予測できたのか判定する必要がある。
比較命令などで実施する分岐命令は、現在のプログラムカウンタの場所からの相対位置でジャンプ先が決まるので、分岐する場合のアドレスは必ず決まっている。 しかしレジスタ相対ジャンプの場合は、「分岐するorしない」以外にも「その分岐アドレスは本当に正しいか」を判定しなければならないという問題がある。
これらをチェックし、もし分岐予測したジャンプアドレスが、実際の戻りアドレスと異なっている場合にもパイプラインフラッシュを発生される機構を導入した。
性能測定
RASの実装有り無しで、性能を比較した。使用したのはCoremarkだ。
サイクル数 | 比率 | |
---|---|---|
RAS無し | 393771 | 1.00 |
RAS有り | 371580 | 0.94 |
約5%の性能向上となった。と言っても5%かあ。。。もっと向上するかと思ってたのになあ。。
もう一つ、IPC推移を取ってみた。X軸が命令数、Y軸は1000命令単位でのIPCをプロットしている。
全体的に少しだけ向上しているが、そこまで目立ったものじゃないなあ。実装がまずいのかもしれない。