RISC-V環境であるE51プロセッサを動作させたときに、Coremarkの公称値と実際の値が少し違っているのを見つけた。
- 64bit版Coremarkバイナリの生成
- Coremarkをriscv-testsの環境でコンパイルしてみる
- RISC-V ISS Spikeでシミュレーション
- BOOMコアでRTLシミュレーション
- 関連記事
はてさて、実際にはどっちが正しいのだろう?RTLでCoremarkをシミュレーションすることはできないだろうか?Coremarkをrocket-chipの環境で動作させるためにはどのようにしたらよいのだろう。
このエントリの情報は古い。以下の記事にてRTLシミュレーションでCoremarkを計測した。
64bit版Coremarkバイナリの生成
BOOMのRTLで実行できるためのバイナリを生成するためには、ちょっとした手順が必要だ。
普段はどのようにリグレッションを行っているかというと、riscv-testsにベンチマークテストパタンとコンパイル方法が記述されており、
riscv64-unknown-elf-gcc \ -T ./common/test.ld -I ./../env -I./common -I./median -I./qsort -I./rsort -I./towers -I./vvadd -I./multiply -I./mm -I./dhrystone -I./spmv -I./mt-vvadd -I./mt-matmul dhrystone_main.o dhrystone.o syscalls.o crt.o \ -o dhrystone.riscv \ -nostdlib -nostartfiles -ffast-math -lgcc riscv64-unknown-elf-objdump --disassemble-all --disassemble-zeroes --section=.text --section=.text.startup --section=.data dhrystone.riscv > dhrystone.riscv.dump
ということで、リンカスクリプトとしてtest.ld
、システムコール系としてsyscalls.o
を使っている。
同じ要領でCoremarkもコンパイルできるだろうか。
Coremarkをriscv-testsの環境でコンパイルしてみる
freedom-e-sdkのCoremarkコンパイル用のディレクトリに移動して、以下のようにしてコマンドを叩いてみた。
/home/msyksphinz/work/freedom-e-sdk/work/build/riscv-gnu-toolchain/riscv64-unknown-elf/prefix/bin/riscv64-unknown-elf-gcc -O2 -fno-common -funroll-loops -finline-functions --param max-inline-insns-auto=20 -falign-functions=4 -falign-jumps=4 -falign-loops=4 -DFLAGS_STR=\""-O2 -fno-common -funroll-loops -finline-functions --param max-inline-insns-auto=20 -falign-functions=4 -falign-jumps=4 -falign-loops=4"\" -DITERATIONS=1 -DPERFORMANCE_RUN=1 -g -march=rv64imac -mabi=lp64 -mcmodel=medany -I/home/msyksphinz/work/freedom-e-sdk/bsp/include -I/home/msyksphinz/work/freedom-e-sdk/bsp/drivers/ -I/home/msyksphinz/work/freedom-e-sdk/bsp/env -I/home/msyksphinz/work/freedom-e-sdk/bsp/env/coreplexip-e51-arty /home/msyksphinz/work/freedom-e-sdk/bsp/env/entry.o core_list_join.o core_main.o core_matrix.o core_state.o core_util.o core_portme.o -L/home/msyksphinz/work/riscv-tools/riscv-tests/benchmarks/ /home/msyksphinz/work/riscv-tools/riscv-tests/benchmarks/syscalls.o -o coremark -Wl,--wrap=malloc -Wl,--wrap=free -Wl,--wrap=open -Wl,--wrap=lseek -Wl,--wrap=read -Wl,--wrap=write -Wl,--wrap=fstat -Wl,--wrap=stat -Wl,--wrap=close -Wl,--wrap=link -Wl,--wrap=unlink -Wl,--wrap=execve -Wl,--wrap=fork -Wl,--wrap=getpid -Wl,--wrap=kill -Wl,--wrap=wait -Wl,--wrap=isatty -Wl,--wrap=times -Wl,--wrap=sbrk -Wl,--wrap=_exit -L. -Wl,--start-group -lwrap -lc -Wl,--end-group -T /home/msyksphinz/work/riscv-tools/riscv-tests/benchmarks/common/test.ld -nostartfiles -L/home/msyksphinz/work/freedom-e-sdk/bsp/env
以下のようなエラーが出た。どうやらターゲットの種類が少し違っているようだ。
/home/msyksphinz/work/freedom-e-sdk/work/build/riscv-gnu-toolchain/riscv64-unknown-elf/prefix/lib/gcc/riscv64-unknown-elf/7.1.0/../../../../riscv64-unknown-elf/bin/ld: /home/msyksphinz/work/riscv-tools/riscv-tests/benchmarks/syscalls.o: can't link hard-float modules with soft-float modules /home/msyksphinz/work/freedom-e-sdk/work/build/riscv-gnu-toolchain/riscv64-unknown-elf/prefix/lib/gcc/riscv64-unknown-elf/7.1.0/../../../../riscv64-unknown-elf/bin/ld: ファイル /home/msyksphinz/work/riscv-tools/riscv-tests/benchmarks/syscalls.o のターゲット特有データの併合に失敗しました /home/msyksphinz/work/freedom-e-sdk/work/build/riscv-gnu-toolchain/riscv64-unknown-elf/prefix/lib/gcc/riscv64-unknown-elf/7.1.0/../../../../riscv64-unknown-elf/bin/ld: /home/msyksphinz/work/riscv-tools/riscv-tests/benchmarks//crt.o: can't link hard-float modules with soft-float modules /home/msyksphinz/work/freedom-e-sdk/work/build/riscv-gnu-toolchain/riscv64-unknown-elf/prefix/lib/gcc/riscv64-unknown-elf/7.1.0/../../../../riscv64-unknown-elf/bin/ld: ファイル /home/msyksphinz/work/riscv-tools/riscv-tests/benchmarks//crt.o のターゲット特有データの併合に失敗しました collect2: error: ld returned 1 exit status
おそらく syscalls.o
のターゲットが異なっていると思うので、以下のようにriscv-tests内のベンチマークコンパイル用Makefileを修正してみる。
diff --git a/benchmarks/Makefile b/benchmarks/Makefile index bc17927..04878d4 100644 --- a/benchmarks/Makefile +++ b/benchmarks/Makefile @@ -50,7 +50,7 @@ HOST_COMP = gcc $(HOST_OPTS) RISCV_PREFIX ?= riscv$(XLEN)-unknown-elf- RISCV_GCC ?= $(RISCV_PREFIX)gcc -RISCV_GCC_OPTS ?= -mcmodel=medany -static -std=gnu99 -O2 -ffast-math -fno-common -fno-builtin-printf +RISCV_GCC_OPTS ?= -mcmodel=medany -static -std=gnu99 -O2 -ffast-math -fno-common -fno-builtin-printf -march=rv64imac -mabi=lp64 RISCV_LINK ?= $(RISCV_GCC) -T $(src_dir)/common/test.ld $(incs) RISCV_LINK_MT ?= $(RISCV_GCC) -T $(src_dir)/common/test-mt.ld RISCV_LINK_OPTS ?= -nostdlib -nostartfiles -ffast-math -lgcc
これで再度コンパイルすると、エラーは発生するが syscalls.o
は作成されているようだ。
/home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/../../../../riscv64-unknown-elf/bin/ld: /home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/libgcc.a(adddf3.o): can't link hard-float modules with soft-float modules /home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/../../../../riscv64-unknown-elf/bin/ld: ファイル /home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/libgcc.a(adddf3.o) のターゲット特有データの併合に失敗しました /home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/../../../../riscv64-unknown-elf/bin/ld: /home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/libgcc.a(gedf2.o): can't link hard-float modules with soft-float modules /home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/../../../../riscv64-unknown-elf/bin/ld: ファイル /home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/libgcc.a(gedf2.o) のターゲット特有データの併合に失敗しました /home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/../../../../riscv64-unknown-elf/bin/ld: /home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/libgcc.a(muldf3.o): can't link hard-float modules with soft-float modules /home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/../../../../riscv64-unknown-elf/bin/ld: ファイル /home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/libgcc.a(muldf3.o) のターゲット特有データの併合に失敗しました /home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/../../../../riscv64-unknown-elf/bin/ld: /home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/libgcc.a(subdf3.o): can't link hard-float modules with soft-float modules /home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/../../../../riscv64-unknown-elf/bin/ld: ファイル /home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/libgcc.a(subdf3.o) のターゲット特有データの併合に失敗しました /home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/../../../../riscv64-unknown-elf/bin/ld: /home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/libgcc.a(floatundidf.o): can't link hard-float modules with soft-float modules /home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/../../../../riscv64-unknown-elf/bin/ld: ファイル /home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/libgcc.a(floatundidf.o) のターゲット特有データの併合に失敗しました /home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/../../../../riscv64-unknown-elf/bin/ld: /home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/libgcc.a(_clzsi2.o): can't link hard-float modules with soft-float modules /home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/../../../../riscv64-unknown-elf/bin/ld: ファイル /home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/libgcc.a(_clzsi2.o) のターゲット特有データの併合に失敗しました /home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/../../../../riscv64-unknown-elf/bin/ld: /home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/libgcc.a(_clz.o): can't link hard-float modules with soft-float modules /home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/../../../../riscv64-unknown-elf/bin/ld: ファイル /home/msyksphinz/riscv/lib/gcc/riscv64-unknown-elf/6.1.0/libgcc.a(_clz.o) のターゲット特有データの併合に失敗しました
以下のようにして再度Coremarkをコンパイルしてみると、エラー無くコンパイルできた。
${REPO_FREEDOM}/work/build/riscv-gnu-toolchain/riscv64-unknown-elf/prefix/bin/riscv64-unknown-elf-gcc \ -O2 -fno-common -funroll-loops -finline-functions --param max-inline-insns-auto=20 \ -falign-functions=4 -falign-jumps=4 -falign-loops=4 \ -DFLAGS_STR=\""-O2 -fno-common -funroll-loops -finline-functions --param max-inline-insns-auto=20 -falign-functions=4 -falign-jumps=4 -falign-loops=4"\" \ -DITERATIONS=1 -DPERFORMANCE_RUN=1 -g -march=rv64imac -mabi=lp64 -mcmodel=medany \ -I${REPO_FREEDOM}/bsp/include -I${REPO_FREEDOM}/bsp/drivers/ -I${REPO_FREEDOM}/bsp/env -I${REPO_FREEDOM}/bsp/env/coreplexip-e51-arty \ ${REPO_FREEDOM}/bsp/env/entry.o \ core_list_join.o core_main.o core_matrix.o core_state.o core_util.o core_portme.o \ -L/home/msyksphinz/work/riscv-tools/riscv-tests/benchmarks/ \ /home/msyksphinz/work/riscv-tools/riscv-tests/benchmarks/syscalls.o \ -o coremark \ -Wl,--wrap=malloc -Wl,--wrap=free -Wl,--wrap=open -Wl,--wrap=lseek -Wl,--wrap=read -Wl,--wrap=write \ -Wl,--wrap=fstat -Wl,--wrap=stat -Wl,--wrap=close -Wl,--wrap=link -Wl,--wrap=unlink -Wl,--wrap=execve \ -Wl,--wrap=fork -Wl,--wrap=getpid -Wl,--wrap=kill -Wl,--wrap=wait -Wl,--wrap=isatty -Wl,--wrap=times \ -Wl,--wrap=sbrk -Wl,--wrap=_exit -L. -Wl,--start-group -lwrap -lc -Wl,--end-group \ -T ${REPO_RISCV_TESTS}/benchmarks/common/test.ld -nostartfiles -L${REPO_FREEDOM}/bsp/env
RISC-V ISS Spikeでシミュレーション
RISC-VのISSであるSpikeでシミュレーションを行ってみると、以下のようにして実行されていることが分かる。 最後まで到達したから間違いはなさそうかな。
spike -l output/coremark.riscv &> output/coremark.riscv.spike.log
BOOMコアでRTLシミュレーション
同様にBOOMコアで実行してみたのだが、途中でPipelineがHungしてしまった。 メモリストアのところで落ちてしまった。何が悪いのだろうか?
$ make output/coremark.riscv.out CONFIG=BOOMConfig Assertion failed: Pipeline has hung. at core.scala:833 assert (!(idle_cycles.value(13)), "Pipeline has hung.") $ ../boom/util/pipeview-helper.py -f output/coremark.riscv.out > cleaned_trace.out && ~/work/gem5/util/o3-pipeview.py -o pipeview.out --color cleaned_trace.out
2017/05/23追記:RocketChipとBOOMではソフトウェアのバイナリが異なる。BOOMはCompressedISAをサポートしていないようだ。
2017/05/20追記、よく見てみたらRocketを作成する際にメモリマップなどのコンフィグレーションが表示されていた。
ram { 0 { addr 0x80000000; size 0x10000000; }; }; plic { priority 0xc000000; pending 0xc001000; ndevs 2; }; rtc { addr 0x200bff8; }; core { 0 { 0 { isa rv64imafds; timecmp 0x2004000; ipi 0x2000000; plic { m { ie 0xc002000; thresh 0xc200000; claim 0xc200004; }; s { ie 0xc002080; thresh 0xc201000; claim 0xc201004; }; }; }; }; }; plic { addr 0xc000000; size 0x4000000; } ExampleRocketTop { addr 0x60000000; size 0x20000000; } debug { addr 0x0; size 0x1000; } ExampleRocketTop { addr 0x80000000; size 0x10000000; } zeros_0 { addr 0xa000000; size 0x2000000; } clint { addr 0x2000000; size 0x10000; } bootrom { addr 0x1000; size 0x1000; }
関連記事
以下の記事にてCoremarkの動作に成功した。