FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

BOOMの分岐予測機構について調べる (2. BOOMのRAS実装を読む)

BOOMの分岐予測について、boom-docs.orgを読みながら解き明かしていこうと思う。

docs.boom-core.org

いくつかテストパタンを作ってRASの挙動を確認してみることにした。作ってみたのは以下のようなマイクロベンチマーク

.section    .text
dummy_call:
    ret

    .global     recurse_add
recurse_add:
    bnez    a0, _next
    li      a0, 0
    ret
_next:
    addi    sp, sp,-24
    sd      ra, 8(sp)
    sd      a0, 16(sp)
    addi    a0, a0, -1
    jal recurse_add
    jal dummy_call
    mv      t0, a0
    ld      a0, 16(sp)
    ld      ra, 8(sp)
    add     a0, t0, a0
    addi    sp, sp, 24
    ret

jalrでもjalでも良いけど、現在のPC+4をRASで積み上げていくためのコード。C言語で書くと単純すぎて最適化されてしまうためアセンブリで書いた。

このコードの目的は、recurse_addを呼び出すことによりRASに積み上げられ、投機実行された次のdummy_callの呼び出しもRASに積まれることを想定している。 2回分RASに積み上げたうえで、retrecurse_addからの1回なのでRASから1回しか取り出されないはずなので、そこで矛盾が生じるのをどのように処理しているのかをチェックしている。

まず、RASへの書き込みはwrite_validにより引き起こされるが、この段階でras_idxがインクリメントされている。そして投機的に別のジャンプ命令によるRAS登録が想定されている。

以下のように波形を確認すると、RAS[4]への登録後に投機的に次々とエントリが登録されていることが分かる。

f:id:msyksphinz:20210805001940p:plain

投機的に登録されたものについては、バックエンドからのフラッシュ情報によりリストアすることができる。 以下の図では、バックエンド側からのredirect_flushによりras_idx=4から先のRASの情報をフラッシュしている。

f:id:msyksphinz:20210805002348p:plain