FPGA開発日記

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

SonicBOOMのデザインを読み解く (1. 環境の構築とシミュレーション)

SonicBOOMのCoreMark値はそれなりに高く、普通にパイプラインを組むだけではおよそ出すことのできないくらいの性能が出ている。これがどこから来ているのか解析したいという話があったので、少し見てみることにした。

ツールチェインのビルド

まずはChipyardを使ってSonicBOOMのシミュレーション環境を構築することにした。Chipyardの環境は1.4.0を使っている。

git clone git@github.com:ucb-bar/chipyard.git -b 1.4.0

ツールチェインは、少し最新版を使う必要がある。私の環境ではGCC7.2ベースの環境しかないので、Chipyardの環境を構築しておく。

./scripts/init-submodules-no-riscv-tools.sh
./scripts/build-toolchains.sh --ignore-qemu riscv-tools

これには結構な時間がかかる。一晩くらい待たないとダメだろう。また、QEMUは使わない割にビルドに時間がかかるので、--ignore-qemuを設定した。

全てのビルドが完了すると、source ./env.sh(このenv.shはツールチェインのビルドが完了すると自動的に作られる)を実行して環境を整える。

BOOMのビルド

BOOMのサイクル情報を取得したいので、以下の変更を施してログを取りやすくした。

以下の変更は、WithBoomCommitLogPrintfを追加してBOOMの実行ログを生成する。

diff --git a/src/main/scala/common/config-mixins.scala b/src/main/scala/common/config-mixins.scala
index fc20726c..8482bc5e 100644
--- a/src/main/scala/common/config-mixins.scala
+++ b/src/main/scala/common/config-mixins.scala
@@ -131,6 +131,7 @@ class WithNSmallBooms(n: Int = 1, overrideIdOffset: Option[Int] = None) extends
  */
 class WithNMediumBooms(n: Int = 1, overrideIdOffset: Option[Int] = None) extends Config(
   new WithTAGELBPD ++ // Default to TAGE-L BPD
+  new WithBoomCommitLogPrintf ++
   new Config((site, here, up) => {
     case TilesLocated(InSubsystem) => {
       val prev = up(TilesLocated(InSubsystem), site)
@@ -178,6 +179,7 @@ class WithNMediumBooms(n: Int = 1, overrideIdOffset: Option[Int] = None) extends
  */
 class WithNLargeBooms(n: Int = 1, overrideIdOffset: Option[Int] = None) extends Config(
   new WithTAGELBPD ++ // Default to TAGE-L BPD
+  new WithBoomCommitLogPrintf ++
   new Config((site, here, up) => {
     case TilesLocated(InSubsystem) => {
       val prev = up(TilesLocated(InSubsystem), site)

さらに、以下のようにprintf()を修正して、ログの解析をし易くする。CSR.timeを追加してサイクル情報を取得する。

diff --git a/src/main/scala/exu/core.scala b/src/main/scala/exu/core.scala
index 579fce89..014b31d8 100644
--- a/src/main/scala/exu/core.scala
+++ b/src/main/scala/exu/core.scala
@@ -1334,14 +1334,15 @@ class BoomCore(usingTrace: Boolean)(implicit p: Parameters) extends BoomModule
       // To allow for diffs against spike :/
       def printf_inst(uop: MicroOp) = {
         when (uop.is_rvc) {
-          printf("(0x%x)", uop.debug_inst(15,0))
+          printf("DASM(0x%x)", uop.debug_inst(15,0))
         } .otherwise {
-          printf("(0x%x)", uop.debug_inst)
+          printf("DASM(0x%x)", uop.debug_inst)
         }
       }

       when (rob.io.commit.arch_valids(w)) {
-        printf("%d 0x%x ",
+        printf("%d %d 0x%x ",
+          csr.io.time,
           priv,
           Sext(rob.io.commit.uops(w).debug_pc(vaddrBits-1,0), xLen))
         printf_inst(rob.io.commit.uops(w))

RISC-V Coremarkのビルド

RISC-V CoremarkはChipyardのsoftware/coremarkに格納されている。build.shを実行すれば自動的にビルドが行われるのだが、シミュレーション時間を短縮するためITERATIONS=10に設定する。

diff --git a/build-coremark.sh b/build-coremark.sh
index 2449d2d..8f77f98 100755
--- a/build-coremark.sh
+++ b/build-coremark.sh
@@ -9,8 +9,8 @@ cd $BASEDIR/$CM_FOLDER

 # run the compile
 echo "Start compilation"
-make PORT_DIR=../riscv64 compile
+make PORT_DIR=../riscv64 ITERATIONS=10 compile
 mv coremark.riscv ../

-make PORT_DIR=../riscv64-baremetal compile
+make PORT_DIR=../riscv64-baremetal ITERATIONS=10 compile
 mv coremark.bare.riscv ../
cd software/coremark
./build.sh

BOOMのビルドとRISC-V CoremarkのRTLシミュレーション

まず、BOOMのビルドを行い、シミュレーションを実行する。

cd sims/verilator
make CONFIG=MediumBoomConfig debug
./simulator-chipyard-MediumBoomConfig-debug --verbose ../../software/coremark/riscv-coremark/coremark.bare.riscv 2>&1 | tee coremark.medium.log

シミュレーションが完了すると、coremark.medium.logが生成される。命令情報を除去すると、Coremarkの実行結果を見ることができる。

grep -v DASM coremark.medium.log
using random seed 1618643897
This emulator compiled with JTAG Remote Bitbang client. To enable, use +jtag_rbb_enable=1.
Listening on port 64406
2K performance run parameters for coremark.
CoreMark Size    : 666
Total ticks      : 2605475
Total time (secs): %f
Iterations/Sec   : %f
ERROR! Must execute for at least 10 secs for a valid result!
Iterations       : 10
Compiler version : GCC9.2.0
link.ld
Memory location  : Please put data memory location here
                        (e.g. code in flash, data on heap etc)
seedcrc          : 0xe9f5
[0]crclist       : 0xe714
[0]crcmatrix     : 0x1fd7
[0]crcstate      : 0x8e3a
[0]crcfinal      : 0xfcaf
Errors detected
*** PASSED *** Completed after 2797178 cycles
[UART] UART0 is here (stdin/stdout).

2,605,475サイクルなので、CMK/MHz的には3.83CMK/MHzだな。まあ、論文の値に近い。

命令数を取得する。start_timeからstop_timeまでの値を取得すれば良かろう。

0000000080002218 <start_time>:
    80002218:   c00027f3                rdcycle a5
    8000221c:   00001717                auipc   a4,0x1
    80002220:   64f73a23                sd      a5,1620(a4) # 80003870 <start_time_val>
    80002224:   8082                    ret

0000000080002226 <stop_time>:
    80002226:   c00027f3                rdcycle a5
    8000222a:   00001717                auipc   a4,0x1
    8000222e:   62f73f23                sd      a5,1598(a4) # 80003868 <stop_time_val>
    80002232:   8082                    ret
grep -n -e 80002218 -e 80002226 coremark.medium.log
13705:               10976 3 0x0000000080002218 DASM(0xc00027f3) x15 0x0000000000002adf
3689644:             2616451 3 0x0000000080002226 DASM(0xc00027f3) x15 0x000000000027ec82

3,689,644 - 13,705 = 3,675,939 命令となっている。2,605,475 サイクルなので、IPCは1.410となっている。

全体的なIPCを観察する

Coremark全体のログから、1000命令毎にサイクル数を抽出してIPCを算出する。

f:id:msyksphinz:20210418002334p:plain

IPCの高い所だと最大の2.0に近いところまで来ている。最初の方に注目すると、matrix_mul_matrix()のあたりがIPC=2に近いようだ。

確かに、この辺は殆どストールなく2命令を同時に完了することができているようだ。

               48494 3 0x000000008000189a c.beqz  a0, pc + 102
               48513 3 0x000000008000189c c.li    t4, 0 x29 0x0000000000000000
               48514 3 0x000000008000189e addw    t3, t4, t5 x28 0x0000000000000000
               48515 3 0x00000000800018a2 c.slli  t3, 32 x28 0x0000000000000000
               48516 3 0x00000000800018a4 srli    t3, t3, 30 x28 0x0000000000000000
               48517 3 0x00000000800018a8 c.add   t3, t6 x28 0x0000000080003c68
               48517 3 0x00000000800018aa c.mv    a2, t4 x12 0x0000000000000000
               48518 3 0x00000000800018ac c.mv    a3, t5 x13 0x0000000000000000
               48518 3 0x00000000800018ae c.li    a1, 0 x11 0x0000000000000000
               48519 3 0x00000000800018b0 slli    a4, a3, 32 x14 0x0000000000000000
               48519 3 0x00000000800018b4 slli    a5, a2, 32 x15 0x0000000000000000
               48520 3 0x00000000800018b8 c.srli  a4, 32 x14 0x0000000000000000
               48520 3 0x00000000800018ba c.srli  a5, 32 x15 0x0000000000000000
               48521 3 0x00000000800018bc c.slli  a4, 1 x14 0x0000000000000000
               48521 3 0x00000000800018be c.slli  a5, 1 x15 0x0000000000000000
               48534 3 0x00000000800018c0 c.add   a4, t1 x14 0x0000000080003b24
               48534 3 0x00000000800018c2 c.add   a5, a7 x15 0x0000000080003bc6
               48535 3 0x00000000800018c4 lh      a4, 0(a4) x14 0x0000000000000014
               48535 3 0x00000000800018c8 lh      a5, 0(a5) x15 0x0000000000000002
               48536 3 0x00000000800018cc c.addiw a3, 1 x13 0x0000000000000001
               48536 3 0x00000000800018ce c.addw  a2, a0 x12 0x0000000000000009
               48540 3 0x00000000800018d0 mulw    a5, a4, a5 x15 0x0000000000000028
               48546 3 0x00000000800018d4 c.addw  a1, a5 x11 0x0000000000000028
               48547 3 0x00000000800018d6 bne     a6, a3, pc - 38
               48548 3 0x00000000800018b0 slli    a4, a3, 32 x14 0x0000000100000000
               48549 3 0x00000000800018b4 slli    a5, a2, 32 x15 0x0000000900000000
               48549 3 0x00000000800018b8 c.srli  a4, 32 x14 0x0000000000000001
               48550 3 0x00000000800018ba c.srli  a5, 32 x15 0x0000000000000009
               48550 3 0x00000000800018bc c.slli  a4, 1 x14 0x0000000000000002
               48551 3 0x00000000800018be c.slli  a5, 1 x15 0x0000000000000012
               48551 3 0x00000000800018c0 c.add   a4, t1 x14 0x0000000080003b26
               48552 3 0x00000000800018c2 c.add   a5, a7 x15 0x0000000080003bd8
               48552 3 0x00000000800018c4 lh      a4, 0(a4) x14 0x0000000000000017
               48553 3 0x00000000800018c8 lh      a5, 0(a5) x15 0x0000000000005f0a
               48553 3 0x00000000800018cc c.addiw a3, 1 x13 0x0000000000000002
               48554 3 0x00000000800018ce c.addw  a2, a0 x12 0x0000000000000012
               48554 3 0x00000000800018d0 mulw    a5, a4, a5 x15 0x00000000000889e6