FPGA開発日記

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

SPEC2006/SPEC2017をRISC-V環境で実行するためのリポジトリを構築する

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は以下の主要なコンポーネントをインストールする:

  1. 基本的なビルドツール: build-essential, gcc, g++, make, perl, python3など
  2. RISC-V向けGNU Toolchain: riscv-collab提供の2025.10.28リリース版
  3. QEMUのビルド依存パッケージ: libglib2.0-dev, ninja-build, texinfoなど
  4. その他の開発ツール: 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-softmmuriscv64-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}

このスクリプトの動作は以下の通り:

  1. ベンチマーク名を引数として受け取る
  2. ベース設定ファイル riscv64_config.cfg をベンチマーク専用の設定ファイルとしてコピー
  3. 静的リンクが必要な場合は、OPTIMIZE フラグに -static を追加
  4. glibc以外のライブラリを使用する場合は、LIBS を追加
  5. 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
  1. monitor_wrapper: QEMU user modeエミュレータを使用してRISC-Vバイナリを実行

    • qemu-riscv64: RISC-V 64bit用のQEMUユーザーモードエミュレータ
    • -L /riscv-linux/sysroot: システムルートディレクトリを指定
  2. コンパイラ設定:

default:
    CC                  = riscv64-unknown-linux-gnu-gcc -std=gnu89
    CXX                 = riscv64-unknown-linux-gnu-g++

    CC_VERSION_OPTION   = --version
    CXX_VERSION_OPTION  = --version
  1. 最適化フラグ:
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/Makefileprepare_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/ に保存