FPGA開発日記

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

RVV-1.0をサポートしたGem5を試す (1. ビルドとデバッグ)

Gem5はアーキテクチャシミュレータで、CPUを含むサブシステムをシミュレーションすることができるツールだ。RISC-Vなどのアーキテクチャをサポートし、サイクル精度シミュレーションも可能だ。

Gem5によるRISC-V Vectorのシミュレーションのサポート状況を確認したくて、ビルド方法を調査することにした。

  1. RivosのGem5作業用リポジトリを使用する。以下のGitリポジトリをクローンする。
git clone https://github.com/rivosinc/gem5.git gem5-rvv -b rivos/dev/joy/initial_RVV_support
  1. ビルド方法は以下。かなり時間がかかる。
scons build/RISCV/gem5.opt -j8

Gem5を用いたサイクル精度シミュレーション:スカラ版ベンチマークの動作

テストのためにRISC-V Vectorized Benchmarkを使用してみる。これは以下からダウンロードしてくる。

git clone https://github.com/RALC88/riscv-vectorized-benchmark-suite.git -b rvv-1.0

これには、とりあえずビルド済みのバイナリが入っているのでそのまま動かしてみよう。

./gem5-rvv/build/RISCV/gem5.opt \
    --debug-flags=O3PipeView \
    --debug-file=trace.out \
    gem5-rvv/configs/example/se.py \
    --cpu-type=DerivO3CPU \
    --caches \
    --cmd=riscv-vectorized-benchmark-suite/_blackscholes/bin/blackscholes_serial.exe \
    -o "1 riscv-vectorized-benchmark-suite/_blackscholes/input/in_256.input output_serial.txt"

オプションについては調べればわかるので省略。m5out/trace.outが生成される。

Konataで表示させてみよう。5GBくらいあるので、少し時間がかかる。

それっぽく見えているな。

Gem5を用いたサイクル精度シミュレーション:ベクトル版ベンチマークの動作

次に、ベクトル化されたベンチマークを動かしてみたいと思う。コマンドを以下のように変更する。

./gem5-rvv/build/RISCV/gem5.opt \
    --debug-flags=O3PipeView \
    --debug-file=trace_v.out \
    gem5-rvv/configs/example/se.py \
    --cpu-type=DerivO3CPU \
    --caches \
    --cmd=riscv-vectorized-benchmark-suite/_blackscholes/bin/blackscholes_vector.exe \
    -o "1 riscv-vectorized-benchmark-suite/_blackscholes/input/in_256.input output_parallel.txt"
gem5 Simulator System.  http://gem5.org
gem5 is copyrighted software; use the --copyright option for details.

gem5 version 21.2.1.0
gem5 compiled May  9 2023 10:19:44
gem5 started May  9 2023 14:39:50
gem5 executing on msyksphinz-tower, pid 1488812
command line: ./gem5-rvv/build/RISCV/gem5.opt --debug-flags=O3PipeView --debug-file=trace_v.out gem5-rvv/configs/example/se.py --cpu-type=DerivO3CPU --caches --cmd=riscv-vectorized-benchmark-suite/_blackscholes/bin/blackscholes_vector.exe -o '1 riscv-vectorized-benchmark-suite/_blackscholes/input/in_256.input output_parallel.txt'
Global frequency set at 1000000000000 ticks per second
warn: No dot file generated. Please install pydot to generate the dot file and pdf.
build/RISCV/mem/mem_interface.cc:791: warn: DRAM device capacity (8192 Mbytes) does not match the address range assigned (512 Mbytes)
build/RISCV/arch/riscv/linux/se_workload.cc:60: warn: Unknown operating system; assuming Linux.
0: system.remote_gdb: listening for remote gdb on port 7000
**** REAL SIMULATION ****
build/RISCV/sim/simulate.cc:194: info: Entering event queue @ 0.  Starting simulation...
zsh: floating point exception (core dumped)  ./gem5-rvv/build/RISCV/gem5.opt --debug-flags=O3PipeView    --caches  -o

おや、落ちてしまったな。これはちょっと問題だ。どこで落ちているのかも記録が残っていない。GDBによるデバッグをしなければならないか…

追記:GDBを当てようとしたら、Gem5自体が落ちてしまった。

# GDB側
target remote localhost:7000
build/RISCV/sim/workload.cc:100: info: system.workload: Waiting for a remote GDB connection on port 7000.
build/RISCV/base/remote_gdb.cc:708: warn: Couldn't read data from debugger.
build/RISCV/sim/simulate.cc:194: info: Entering event queue @ 0.  Starting simulation...
zsh: floating point exception (core dumped)  ./gem5-rvv/build/RISCV/gem5.opt --debug-flags=O3PipeView   --wait-gdb    -o

Debugモードによるビルド

scons build/RISCV/gem5.debug -j$(nproc)

GDBでいろいろデバッグした結果、いくつかのポイントがある。まだこのブランチは問題があるようだ。いくつかの修正が必要となる。

  • alignToPowerOfTwo()の修正が必要となる。0のときは1とする。
diff --git a/src/base/bitfield.hh b/src/base/bitfield.hh
index 1b585da09..8ac3eb813 100644
--- a/src/base/bitfield.hh
+++ b/src/base/bitfield.hh
@@ -491,7 +491,10 @@ popCount(uint64_t val)
 constexpr uint64_t
 alignToPowerOfTwo(uint64_t val)
 {
-    val--;
+  if (val == 0) {
+    return 1;
+  }
+  val--;
     val |= val >> 1;
     val |= val >> 2;
     val |= val >> 4;
  • とりあえず未定義なCSRにアクセスしても良しとする。hpmcounterへのアクセスがサポートしていないようなので、とりあえずの対処となる。
diff --git a/src/arch/riscv/faults.cc b/src/arch/riscv/faults.cc
index eea42fe27..d5100c665 100644
--- a/src/arch/riscv/faults.cc
+++ b/src/arch/riscv/faults.cc
@@ -192,9 +192,9 @@ UnknownInstFault::invokeSE(ThreadContext *tc, const StaticInstPtr &inst)
 void
 IllegalInstFault::invokeSE(ThreadContext *tc, const StaticInstPtr &inst)
 {
-    auto *rsi = static_cast<RiscvStaticInst *>(inst.get());
-    panic("Illegal instruction 0x%08x at pc %s: %s", rsi->machInst,
-        tc->pcState(), reason.c_str());
+    // auto *rsi = static_cast<RiscvStaticInst *>(inst.get());
+    // panic("Illegal instruction 0x%08x at pc %s: %s", rsi->machInst,
+    //     tc->pcState(), reason.c_str());
 }

これで再度ベンチマークを実行したが、initiateAcc()がないと怒られてしまった。これはなんでだ?もうちょっとデバッグを続けるか、きっぱりとRivosのGem5を諦めてしまうかは微妙なところだなあ。

Global frequency set at 1000000000000 ticks per second
warn: No dot file generated. Please install pydot to generate the dot file and pdf.
build/RISCV/mem/mem_interface.cc:791: warn: DRAM device capacity (8192 Mbytes) does not match the address range assigned (512 Mbytes)
build/RISCV/arch/riscv/linux/se_workload.cc:60: warn: Unknown operating system; assuming Linux.
0: system.remote_gdb: listening for remote gdb on port 7000
**** REAL SIMULATION ****
build/RISCV/sim/simulate.cc:194: info: Entering event queue @ 0.  Starting simulation...
PARSEC Benchmark Suite
build/RISCV/sim/mem_state.cc:443: info: Increasing stack size by one page.
Num of Options: 256
Num of Runs: 100
Size of data: 10240

BlackScholes Initialization took 0.00000000 secs
build/RISCV/cpu/static_inst.hh:315: panic: initiateAcc not defined!
Memory Usage: 625724 KBytes
Program aborted at tick 682762500