FPGA開発日記

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

自作CPUにベクトル命令を追加する実装検討(44. AXPYベンチマークの改善)

前回、ベンチマークのためにAXPYを動かした。 ハザードが発生しても、投機実行を継続するためにuopを生成し続けるポリシを採用すると、MSHRへの割り当て以外の時にも長いハザードが発生してしまい、結果的に性能が大きく落ちていた。

ISS CYCLE is updated to RTL = 000000000001e90c
ISS CYCLE is updated to RTL = 0000000000027c51
// 64KBのデータ計算で37,701サイクルかかっている。

そこで、MSHRへの割り当てのハザードの時だけuopを生成し続け、そうでないとき(L1Dのコンフリクトなど)のときは即時uopの生成を取り消してリトライするようなポリシを取り入れる。

これで性能がどれくらい上がるか見てみよう。

ISS CYCLE is updated to RTL = 000000000001e90c
ISS CYCLE is updated to RTL = 00000000000251a9
// 64KBのデータ計算で、26,781サイクルかかっている。

うーん、一応性能は上がったが、まだまだ理想の性能には届いてないなあ。

まず、かならずL1Dキャッシュをミスする構成なので、2回のvle64.vをパイプラインが通過することになる。 1命令あたりで VLEN/DLEN*LMUL =512/128*8=32 サイクルかかり、2回通ることになるので1命令あたり64サイクル消費し、 さらにこれを2命令、128サイクル消費する。 64KBのイタレーションで必要なのは、64B*1024*8-bit = 524,288-bitの処理が必要で、VLEN=512で、LMUL=8なので、524,288/VLEN/LMUL=128-iterations 必要である。

さらにストア命令がアドレス生成のために同様に32サイクル(これはキャッシュミスはストアバッファ上で処理される)必要で、トータルでLSUパイプラインは160サイクルが消費される。

したがって、26,781-cycle/128-iteration = 209-cycle でできる計算になる。40サイクルくらいの誤差があるかな?でもけた違いに悪い数字ではない。

逆に言えば、vle64.vの2回パイプラインを消費する構造をどうにかしてカットできれば、160-32*2 = 98-cycleでイタレーションが回せることになる。 こうすると、12,544-cycleで回せることになり、さらなる性能向上が見込めることになる。