SPEC CPU2006およびSPEC CPU2017は、プロセッサの性能を評価するための標準的なベンチマークスイートであり、これをRISC-V向けにコンパイルするリポジトリを構築している。
リポジトリの全体構成
本リポジトリは、SPEC CPU2006/2017をRISC-V向けにクロスコンパイルし、QEMUユーザーモードエミュレーション上で実行するための環境を提供する。リポジトリのディレクトリ構造は以下のようになっている:
bench_trace_env/ ├── Dockerfile # 実行環境構築用のDockerfile ├── Makefile # トップレベルMakefile ├── cpu2017-1_0_2.iso # SPEC CPU2017のISOイメージ ├── SPECCPU_2006_v1.1.iso # SPEC CPU2006のISOイメージ ├── spec2006_work/ # SPEC2006作業ディレクトリ ├── spec2006_cdrom/ # SPEC2006 CDマウント先 └── spec2017_cdrom/ # SPEC2017 CDマウント先
Docker環境
本リポジトリでは、Ubuntu 24.04をベースイメージとして使用している。Dockerfileは以下の主要なコンポーネントをインストールする:
- 基本的なビルドツール: build-essential, gcc, g++, make, perl, python3など
- RISC-V向けGNU Toolchain: riscv-collab提供の2025.10.28リリース版
- QEMUのビルド依存パッケージ: libglib2.0-dev, ninja-build, texinfoなど
- その他の開発ツール: cmake, git, sqlite3, gnuplotなど
FROM ubuntu:24.04 ENV DEBIAN_FRONTEND=noninteractive \ LANG=C.UTF-8 ARG RISCV_ARG=/riscv ENV RISCV=${RISCV_ARG}
RISC-V Toolchainは、ソースからビルドするのではなく、プリビルドバイナリを利用している:
ENV RISCV=/riscv-linux RUN curl -L https://github.com/riscv-collab/riscv-gnu-toolchain/releases/download/2025.10.28/riscv64-glibc-ubuntu-24.04-gcc.tar.xz | tar xJ && \ mv /tmp/riscv ${RISCV} ENV PATH=$PATH:$RISCV/bin ENV LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$RISCV/lib
toolchainは /riscv-linux にインストールされ、riscv64-unknown-linux-gnu-gcc などのクロスコンパイラが利用可能になる。
トップレベルMakefileの役割
ルートディレクトリの Makefile は、Docker環境とQEMUのビルドを管理する:
build:
docker build -t spec2017-runner .
$(MAKE) build-qemu
run:
docker run --rm -it -v "${HOME}:${HOME}" --user $(shell id -u):$(shell id -g) -w "${PWD}" spec2017-runner
QEMU_VERSION=10.0.6
build-qemu: .build_qemu
.build_qemu:
wget https://download.qemu.org/qemu-$(QEMU_VERSION).tar.xz
tar xJf qemu-$(QEMU_VERSION).tar.xz
cd qemu-$(QEMU_VERSION) && \
mkdir -p build && cd build && \
../configure --disable-rust --target-list=riscv64-softmmu,riscv64-linux-user && \
make -j32
touch $@
build ターゲットは:
1. Dockerイメージをビルド
2. QEMUをソースからビルド(riscv64-softmmuとriscv64-linux-userターゲット)
QEMUのビルドは、現状なぜかDocker内でビルドするとうまく動いてくれないので、Docker外でビルドしている。これの原因は不明。
run ターゲットは、ホストのホームディレクトリをマウントして、現在のユーザー権限でコンテナを起動する。これにより、ビルド成果物の権限問題を回避している。
SPEC2006作業環境
spec2006_work/Makefile
spec2006_work/Makefile は、SPEC2006のインストールと各ベンチマークの実行を管理する:
bench_lists += 400.perlbench bench_lists += 401.bzip2 bench_lists += 403.gcc # bench_lists += 410.bwaves # bench_lists += 416.gamess bench_lists += 429.mcf ...
インストールとビルドのフローは以下の通り:
prepare_spec2006: .prepare_spec2006
.prepare_spec2006:
cd ../spec2006_cdrom && ./install.sh -f -d $(PWD)/spec2006_installed
touch $@
$(RUN_BENCH_LISTS):
./run.sh $(subst run_,,$@)
.prepare_spec2006 というスタンプファイルを使用して、重複インストールを防いでいる。
run.sh: ベンチマーク実行スクリプト
run.sh は、個別のベンチマークを実行するためのラッパースクリプトである:
#!/bin/bash
CPU2006_DIR=`realpath ./spec2006_installed`
TARGET_LIB=glibc
LINK_TYPE=dynamic
BENCHMARK=$1
CONFIG=_opt_flags_${TARGET_LIB}_${BENCHMARK}
CONFIG_FILE=${CPU2006_DIR}/config/${CONFIG}.cfg
cp `realpath riscv64_config.cfg` ${CONFIG_FILE}
このスクリプトの動作は以下の通り:
- ベンチマーク名を引数として受け取る
- ベース設定ファイル
riscv64_config.cfgをベンチマーク専用の設定ファイルとしてコピー - 静的リンクが必要な場合は、
OPTIMIZEフラグに-staticを追加 - glibc以外のライブラリを使用する場合は、
LIBSを追加 - SPEC環境をセットアップして、
runspecコマンドでビルドと実行
cd ${CPU2006_DIR} && . ${CPU2006_DIR}/shrc
printenv SPEC
ulimit -s unlimited
${CPU2006_DIR}/bin/runspec -a setup -c ${CONFIG} -I ${BENCHMARK}
${CPU2006_DIR}/bin/runspec -a run -c ${CONFIG} -I ${BENCHMARK}
ulimit -s unlimited により、スタックサイズの制限を解除している。これは、一部のベンチマークで大きなスタック領域が必要になるためである。
riscv64_config.cfg: RISC-V向け設定ファイル
riscv64_config.cfg は、SPEC2006をRISC-V向けにビルドするための設定を定義している:
copies = 1 iterations = 1 ext = gcc makeflags = -j32 output_format = csv runlist = int strict_rundir_verify = 0 monitor_wrapper = /home/kimura/work/bench_trace_env/qemu-10.0.6/build/qemu-riscv64 -L /riscv-linux/sysroot $command
monitor_wrapper: QEMU user modeエミュレータを使用してRISC-Vバイナリを実行
qemu-riscv64: RISC-V 64bit用のQEMUユーザーモードエミュレータ-L /riscv-linux/sysroot: システムルートディレクトリを指定
コンパイラ設定:
default:
CC = riscv64-unknown-linux-gnu-gcc -std=gnu89
CXX = riscv64-unknown-linux-gnu-g++
CC_VERSION_OPTION = --version
CXX_VERSION_OPTION = --version
- 最適化フラグ:
default:
OPTIMIZE = -g -Ofast -funroll-loops -flto -flto-partition=one -fno-builtin-memcpy -fno-builtin-memmove
EXTRA_OPTIMIZE = -mabi=lp64d
PORTABILITY = -DSPEC_CPU_LP64
LDCXXFLAGS = -Wl,--allow-multiple-definition
ディレクトリ構造の詳細
spec2006_work/spec2006_installed/
このディレクトリは、spec2006_work/Makefile の prepare_spec2006 ターゲットによって作成される。SPEC2006のCDROM(spec2006_cdrom)から install.sh スクリプトを実行してインストールされる:
prepare_spec2006: .prepare_spec2006
.prepare_spec2006:
cd ../spec2006_cdrom && ./install.sh -f -d $(PWD)/spec2006_installed
touch $@
インストール後のディレクトリ構造:
spec2006_installed/ ├── benchspec/ # ベンチマークソースコードとビルド成果物 │ └── CPU2006/ │ ├── 400.perlbench/ │ ├── 401.bzip2/ │ ├── 403.gcc/ │ └── ... ├── bin/ # SPEC実行ツール │ └── runspec ├── config/ # 設定ファイル ├── result/ # 実行結果 └── tmp/ # 一時ファイル
各ベンチマークディレクトリの下には、以下のサブディレクトリが作成される:
- src/: ソースコード
- build/: ビルド成果物
- run/: 実行ディレクトリと入力データ
- exe/: 実行バイナリ
実行フロー
実際にベンチマークを実行する際のフローをまとめると:
1. Docker環境のビルド
make build
- Dockerイメージ
spec2017-runnerをビルド - QEMUをソースからビルド
2. Dockerコンテナの起動
make run
- ホームディレクトリをマウントしてコンテナを起動
- 以降の作業はコンテナ内で実行
3. SPEC2006のインストールとビルド
cd spec2006_work make
- SPEC2006をインストール(
.prepare_spec2006) - 有効化されている各ベンチマークを順次ビルド・実行
4. 個別ベンチマークの実行
make run_400.perlbench
run.sh 400.perlbenchを実行- ベンチマーク専用の設定ファイルを生成
runspec -a setupでビルドrunspec -a runで実行- 結果は
spec2006_installed/result/に保存