FPGA開発日記

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

RocketChip RISC-V実装RTLにてベンチマークを計測する(3. -O3によるCoremarkコンパイル)

ずいぶん大昔の記事を引っ張り出してきたが、RASの解析などを行うにあたり、BOOMの実装を調べたくて、BOOMの実性能がどうなっているのか調べたくなってきたので調査している。

msyksphinz.hatenablog.com

msyksphinz.hatenablog.com

gem5を使えばBOOMのパイプライントレースの解析を行うことができる。これで自前でコンパイルしたCoremarkを解析して、BOOMの性能を解析したい。

-O3 -funroll-loops を加えたCoremarkのコンパイル

github.com

funroll-loopsと-O3を加えて、評価用のCoremarkプログラムをコンパイルした。RocketもBOOMも64bitで動作するし、自作ISSも64bitモードに対応しているのでこれで比較する。

start_time(), stop_time()の間の命令数

grep -e 80006a90 -e 80006aa0 coremark.sw.log
     15260:M:MBar:[0000000080006a90][P000080006a90] 00000033 : add        r00,r00,r00          r00=>0000000000000000 r00=>0000000000000000
    370114:M:MBar:[0000000080006aa0][P000080006aa0] 00000033 : add        r00,r00,r00          r00=>0000000000000000 r00=>0000000000000000

というわけで命令数的には35万命令程度なのだが、-funroll-loopsを加えると命令数が増えてしまった。不思議。

BOOM(2-way)での実行

BOOMで当該バイナリを実行して、同様にstart_time()stop_time()のサイクル数を解析した。

make CONFIG=BOOMConfig output/coremark.riscv.out
../boom/util/pipeview-helper.py -f output/coremark.riscv.out > cleaned_trace.out
/work/gem5/util/o3-pipeview.py -o pipeview.out --colorcleaned_trace.out

前の記事にも書いたが、output/coremark.riscv.outの先頭にある1行を削除しないと解析されないので注意。

f:id:msyksphinz:20170417000310p:plain

$ grep -e start_time -e stop_time coremark.dmp
0000000080006a90 <start_time>:
    80006a98:   1e02aa23                sw      zero,500(t0) # 8000dc88 <start_time_val>
0000000080006aa0 <stop_time>:
    80006aa8:   1e02a023                sw      zero,480(t0) # 8000dc84 <stop_time_val>

$ grep -e 80006a90 -e 80006aa0 pipeview.out
[..................f..di...cr....................................................]-(     1168480000) 0x0080006a90.0 add zero, zero, zero      [    619748]
[====================f==di=======================================================]-(     1168480000) 0x0080006aa0.0 -----add zero, zero, zero [    619752]
[=========================================================f======================]-(     1662480000) 0x0080006a90.0 -----add zero, zero, zero [   1284475]
[.....................................................................f..di...cr.]-(     1666800000) 0x0080006aa0.0 add zero, zero, zero      [   1291132]
[======================f==di=====================================================]-(     1671200000) 0x0080006a90.0 -----add zero, zero, zero [   1296453]
[========================f=======================================================]-(     1671200000) 0x0080006aa0.0 -----add zero, zero, zero [   1296457]

ちなみにpipeiew.outの見方だが、------アセンブリ命令の前についているのは、パイプラインフラッシュされる対象の命令なので無視。こう見ると、start_time()からstop_time()までのサイクル数は大よそ { \displaystyle
1666800-1168480 = 498320
} あれ、サイクル数的にはだいぶ増えたぞ?

途中のサイクルを見ていると、

[................................................................f..di..c.r......]-(     1279680000) 0x0080003690.0 lh a2, 0(s8)              [    764124]
[................................................................f..di...cr......]-(     1279680000) 0x0080003694.0 addw a4, s10, s6          [    764125]
[.................................................................f..di...cr.....]-(     1279680000) 0x0080003698.0 addiw a5, a5, 4           [    764126]
[.................................................................f..d.i...cr....]-(     1279680000) 0x008000369c.0 mulw s10, ra, s7          [    764127]
[==================================================================f==d==========]-(     1279680000) 0x00800036a0.0 -----addw t6, t6, a3      [    764128]
[==================================================================f==d==========]-(     1279680000) 0x00800036a4.0 -----mulw ra, t5, t0      [    764129]
[===================================================================f==d=========]-(     1279680000) 0x00800036a8.0 -----addw s7, t6, s10     [    764130]
[===================================================================f==d=========]-(     1279680000) 0x00800036ac.0 -----mulw a6, t2, a2      [    764131]
[====================================================================f==d========]-(     1279680000) 0x00800036b0.0 -----addw t4, s7, ra      [    764132]
[====================================================================f==d========]-(     1279680000) 0x00800036b4.0 -----addw t6, t4, a6      [    764133]
[=====================================================================f==d=======]-(     1279680000) 0x00800036b8.0 -----bne t3, a5, pc - 224 [    764134]
[======================================================================f==d======]-(     1279680000) 0x00800035d8.0 -----addw s8, a4, s6      [    764135]
[======================================================================f==d======]-(     1279680000) 0x00800035dc.0 -----slli s7, a5, 32      [    764136]
[=======================================================================f==d=====]-(     1279680000) 0x00800035e0.0 -----slli t2, a4, 32      [    764137]
[=======================================================================f==d=====]-(     1279680000) 0x00800035e4.0 -----addiw t5, a5, 1      [    764138]
[========================================================================f==d====]-(     1279680000) 0x00800035e8.0 -----srli a3, s7, 32      [    764139]
[========================================================================f==d====]-(     1279680000) 0x00800035ec.0 -----srli s10, t2, 32     [    764140]
[=========================================================================f==d===]-(     1279680000) 0x00800035f0.0 -----addw a2, s8, s6      [    764141]
[=========================================================================f==d===]-(     1279680000) 0x00800035f4.0 -----slli ra, t5, 32      [    764142]
[==========================================================================f=====]-(     1279680000) 0x00800035f8.0 -----slli a4, s8, 32      [    764143]
[==========================================================================f=====]-(     1279680000) 0x00800035fc.0 -----addiw t0, a5, 2      [    764144]
[.............f..di...cr.........................................................]-(     1279760000) 0x0000000800.0 j pc + 0x3c               [    764145]
[...............f.......di...cr..................................................]-(     1279760000) 0x000000083c.0 csrw dscratch, s0         [    764146]

RISC-Vは通常命令領域は0x0080000000から始まるのだが、mulw命令を実行後に突然0x0000000800に飛んでいたりしている。これは何だろう? それはともかく、現在のCoremarkの解析において気になっている部分を見てみよう。

load –> arith –> storeのループ

例えば、

loop 
lw     a0, 0(a1)
add    a0, a0, 1
sw     a0, 0(a3)
...
bltz   loop

みたいなループがある場合、swのメモリオーダを厳密に守ると、次のループのロードがswよりも先に出せず、パイプラインを活用することができない。 これはBOOMではどのように実行しているだろう。

f:id:msyksphinz:20170417001825p:plain

例えばこういうループだな。lbuとsbに依存関係があって、次のループのlbuの実行を遅らせていると確実にパイプラインに影響があるのだが、BOOMではほとんど影響なくストールを生じさせていない。 このあたりは、ストアバッファの中を探索して、無関係なアドレスであれば先にロードを通すなどの処理が行われていると予想する。