FPGA開発日記

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

命令フェッチラインに基づく最適化

マイコンでは一般的なのかもしれないが、プログラムの最適化の1つの方法として命令フェッチラインに基づく最適化というものがある。

これは早い話が、ループの境界がなるべく命令フェッチの範囲を超えないようにし、フェッチ回数を減らすというものだ。

f:id:msyksphinz:20170411005821p:plain

例えば、4命令をループさせるプログラムがあったとして、

data_ready_loop:
    sw      x2,0x00(x1)
    // addi    x2,x2,0x01
    addi    x1,x1,4
    addi    x4,x4,1
    bltu    x4,x5,data_ready_loop

このプログラムをコンパイルすると、以下のようなアセンブラが生成された。

80000090 <data_ready_loop>:
80000090:       0020a023                sw      sp,0(ra) # 80002000 <_sp+0xffffde38>
80000094:       00408093                addi    ra,ra,4
80000098:       00120213                addi    tp,tp,1 # 1 <_tbss_end+0x1>
8000009c:       fe526ae3                bltu    tp,t0,80000090 <data_ready_loop>

現在、自作RISC-Vプロセッサのフェッチラインは128ビットだ。つまり、これが0x10の境界に入っていれば、一度にフェッチしてこれる。 これが、フェッチ境界を跨いでしまったらどうだろう。

800000c8 <data_ready_loop_hit2>:
800000c8:       0020a023                sw      sp,0(ra) # 80002000 <_sp+0xffffde78>
800000cc:       00408093                addi    ra,ra,4
800000d0:       00120213                addi    tp,tp,1 # 1 <_tbss_end+0x1>
800000d4:       fc526ee3                bltu    tp,t0,800000b0 <data_ready_loop_hit>

この場合、このループを実行するのに、2回のフェッチが必要になる。この2種類のループを、RTLシミュレーションで比較した。

  • フェッチアラインに合わせたもの: 151cycle
  • フェッチ境界を跨いだもの : 239cycle

結構な差が出てきた。これはフェッチを2回したことにより、無駄な命令発行をしているということでもある。