Heliodor Linux ベンチマーク
Heliodor は Celox の大規模な外部 Veryl ワークロードです。固定した Linux イメージを 起動し、同じ設計リビジョンと入力を使って Celox のネイティブバックエンド、tiered JIT、 Veryl-CC の同期版と tiered 版を CPU アーキテクチャごとに比較します。 Celox の tiered 版はインタプリタで実行を始め、バックグラウンドでネイティブコードを生成します。 x86-64 では先に軽量なネイティブコードへ切り替え、最適化版が完成すると安全な実行境界で 再度切り替えます。実行中の状態とイベントバッファは保持します。 コード生成のトレースを指定した場合は、最適化版を直接生成します。 Veryl-CC の tiered 版は Cranelift で実行を始め、C の非同期コンパイルが完了すると切り替えます。 これは通常の veryl test --backend cc と同じ aot_c_async=true の設定です。 同期版は明示的に aot_c_async=false とし、C のコンパイル完了を待ってから実行します。 Cranelift 単独の Linux 起動時間はこの比較の有効な尺度を大幅に 超えるため、計測・公開しません。
測定するもの
次の 3 つを分けて計測します。
- 同期バックエンドが設計をコンパイルする時間。
- テストベンチを含め、ワークロード全体を実行する時間。
- コンパイルとシミュレーションを並行させる tiered 実行の起動から Linux 完了までの時間。
実行時間は両シミュレータともテストベンチの処理を含みます。tiered 版は「実行開始まで」「コンパイルと 並行した実行」「Linux 起動完了までの総時間」を別のグラフで表示します。tiered の実行区間には 切り替え前のバックエンドも含まれるため、生成コードだけの速度としては比較しません。 Veryl-CC は C のコンパイル完了前に Cranelift だけで処理を終える場合もあり、 その場合も有効な tiered の測定値として扱います。 起動時間と総時間は設計の解析前から測り、ソースファイルの読み込みと Cargo によるランナーの ビルド時間は含みません。TSV の compile_elapsed_ns は tiered 版では実行開始までの時間を表し、 バックグラウンドのコンパイル全体の時間ではありません。Veryl-CC の同期版・tiered 版はそれぞれ 独立した空の AOT-C キャッシュを使います。
途中までの起動、完了時間の推定、コンパイルだけの結果は、実行成功として扱いません。
有効な結果
次の条件をすべて満たす実行だけを採用します。
- 固定した Heliodor とワークロードのリビジョンを使う。
- 設定された Linux 完了マーカーまで到達する。
- コンパイル時間と実行時間を分けて記録する。
- 意図した Celox / Veryl リビジョンからランナーをビルドする。
- タイムアウトや意味上の不一致を調査できるログを残す。
- Celox の tiered 実行が Linux 完了前に生成コードへ昇格し、生成コードで 1 回以上評価したことを確認する。
- Veryl-CC の tiered 実行で C の非同期コンパイルが有効であり、生成コードかフォールバックで 1 回以上実行したことを確認する。
完了マーカーを固定することで、高速に失敗した実行や未完了の起動を性能向上として 誤って報告することを防ぎます。
ローカル実行
bash scripts/run-heliodor-bench.sh run両方の tiered バックエンドを比較する場合:
HELIODOR_RUNNERS="celox-tiered veryl-cc-tiered" bash scripts/run-heliodor-bench.sh run生成したネイティブコードの性能を繰り返し調べる場合は、ビルドキャッシュを有効にできます。
HELIODOR_RUNNERS=celox \
HELIODOR_CELOX_BUILD_CACHE_DIR="$PWD/target/heliodor/build-cache" \
bash scripts/run-heliodor-bench.sh runランナー単体でも --build-cache-dir DIR を指定できます。ヒット時は解析・最適化・ ネイティブコード生成を省略し、シミュレーション状態は毎回初期化します。 CELOX_BUILD_CACHE の status=hit / status=miss で再利用の有無を確認できます。 ソースの内容と順序、プロジェクト設定と依存関係、テスト名、最適化とパスの設定、 4-state モード、メモリ幅、SLP、診断設定、検出した x86 CPU・OS 機能、 プロジェクトルートを基準とした作業ディレクトリの位置、実行バイナリを照合します。 $readmemh の参照ファイルも内容を確認し、探索候補のファイルが新しく作られた場合も 再ビルドします。キャッシュ検索前に依存側の名前空間とプロパティを解決します。 コンポーネントの Cargo 設定、マニフェスト候補、事前ビルド済み WASM も確認し、 マニフェストの優先順位を決める更新時刻の変更も再ビルドの対象にします。 native コンポーネントライブラリの有無も Cargo の [lib].name 指定を含めて確認し、 ライブラリの追加・削除時には実行ライブラリの選択を更新します。 コンパイル中は入力ファイルを変更しないでください。
キャッシュの依存パスと image のライブラリ・ファイル基準ディレクトリ・診断ソースの パスは、プロジェクトルートを基準とした相対パスで保存します。 ロード時には、現在のプロジェクトルートを使って実際のパスを復元します。 $readmemh に絶対パスを明示した場合は、実際の参照先のハッシュも確認し、 移動先のファイルで元の参照先を置き換えないようにします。 入力と作業ディレクトリの相対位置が同じなら、プロジェクトを移動しても再利用できます。 各ソースの解決済み名前空間もキーに含めます。外部パスは .. で表し、Windows の 別ドライブなど相対化できない場合はキャッシュを使いません。CLI の native image 出力も 相対パスを使い、プロジェクトルートを基準とした相対パスで表せない場合は、書き込み前にエラーにします。 --native-image-input はソースを読み込まず、--project で 指定したプロジェクトのルートを基準にパスを復元します。絶対パスを持つ既存 image もロードできます。 設計中の文字列リテラルは保持されるため、キャッシュは匿名化された成果物ではありません。 以前のキャッシュ形式のエントリは再利用しません。
キャッシュは明示的な指定時だけ有効で、native バックエンドに対応します。 host-qemu のホスト側コード生成や --compile-only --native-image-output でも利用できます。 --native-image-input および --dump-ir-dir との併用はできません。 実行可能コードを保存するため、信頼できるローカルディレクトリを指定してください。 書き込みはアトミックに行い、破損やキャッシュの入出力エラー時は再ビルドします。 削除するにはディレクトリを消してください。古いエントリの自動削除は行いません。
ヒット時の compile_ns はコンパイルではなくロード・初期化の時間です。 実行性能の調査に利用し、ビルド時間や全体の性能を比較する際は無効にしてください。 固定構成の CI gate では常に無効にします。
CI の固定 gate は x86-64 で veryl-cc-sync、celox、celox-tiered、 veryl-cc-tiered を実行します。夜間の AArch64 ジョブも同じ 4 種類を測定し、 固定版のジョブはすべて scripts/heliodor-revision を参照します。suite では成功した バックエンドから順に公開し、他のバックエンド・ワークロード・アーキテクチャの完了を待ちません。 失敗は CI 上で失敗として扱います。
初回は固定した Heliodor checkout の取得にネットワークアクセスが必要です。スクリプトは 使用リビジョン、ビルド構成、完了状態、計測時間を表示します。変更前後の比較には同じ マシンと構成を使ってください。
公開結果はベンチマークダッシュボードの Heliodor Linux に掲載します。
大規模・Linux バージョン別の測定
nightly とプロファイルを取らない手動実行では、次の 9 ケースを x86-64 (ubuntu-24.04)と AArch64(ubuntu-24.04-arm)で測定します。 各ケースで前述の 4 バックエンドを実行します。
| ゲスト Linux カーネル | hart 数 |
|---|---|
| 5.15 | 1、2、4、8 |
| 6.6 | 1、2、4 |
| 7.1 | 1 |
| 7.1(ベクトル有効) | 1 |
Heliodor のリビジョンは 6285682fa0a514077da9d17fee385c7841160025 に固定します。 Linux バージョンはシミュレーション内で起動するゲストのもので、ホスト OS の違いではありません。 次のグループごとに同じ VM で順番に測定し、全体で 36 ジョブを実行します。
| 構成 | アーキテクチャごとの比較グループ |
|---|---|
| 1・2 hart、および x86-64 の 4 hart | 4 バックエンドを 1 ジョブで比較 |
| AArch64 の 4 hart | 2 ジョブ:Celox native と Veryl-CC 同期版、Celox tiered と Veryl-CC tiered |
| 両アーキテクチャの 8 hart | バックエンドごとに別ジョブ |
| すべての SMP 構成(2・4・8 hart) | celox-parallel の 1 ジョブを追加 |
celox-parallel は native バックエンドを並列シミュレーションで 実行し、ホストの vCPU ごとに 1 スレッドを使います(HELIODOR_CELOX_THREADS、既定値は nproc)。 別ジョブにすることで、比較グループの実行時間の上限は変わりません。ダッシュボードでは シングルスレッドの native 実行と並べて「multi-threaded」として表示します。
直近の完走結果では、8 hart の合計は x86-64 で 10〜13 時間、AArch64 で 17〜18 時間です。 AArch64 の 4 hart も合計 5〜7 時間なので、同じ実行方式のペアに分け、ビルド時間を確保しつつ Celox と Veryl-CC を同じ CPU で比較します。別グループ間では同じ CPU を保証しません。 CPU とホストの識別情報を成果物に記録し、各バックエンドの成功した結果を個別に公開します。 各実行のタイムアウトは 1・2 hart が 1 時間、4 hart が 3 時間、8 hart が 5.5 時間です。 未完了・失敗したバックエンドの計測値は公開しません。他の成功したバックエンドの公開は止めません。 8 hart の Veryl テストには 8hart-100m-v1 の調整を適用し、古い 3,000 万サイクルの 上限を、上流の Verilator ラッパーと同じ 1 億サイクルに揃えます。shutdown のアサーションは維持します。 HELIODOR_SUITE=1 は固定した suite リビジョンだけにこの調整を適用し、ジョブログにも記録します。
Linux 7.1 SMP(2・4 hart)は RTL の修正待ちとして対象から除外しています。 どちらも一つの hart で命令の完了が停止し、2 hart では Verilator でも データキャッシュの読み出し待ちと他 hart のロック待ちが再現しました。 この失敗を成功した計測結果として扱うことはありません。
別の HEAD 互換性ジョブでは、上流リビジョン 94e9c5821c24a8941c3ddc3b76daddc7124a855a だけを除外します。 この版のテストベンチには ROM/DRAM 初期化の initial_assign 属性がなく、 固定版 6285682 で追加されています。CI には既知のソース不備による除外と明記し、 シミュレーション成功には数えません。それ以外の HEAD は検証対象のままです。
ダッシュボードには現在の suite のみを、カーネルと hart 数を区別して表示します。 コンパイル・実行・tiered の時間の定義は共通です。 大規模ケースは PR ごとには実行しません。
Linux 6.6 の 4 hart をローカルで実行する例:
HELIODOR_REF=6285682fa0a514077da9d17fee385c7841160025 \
HELIODOR_TESTS=test_soc_66_smp_linux_boot_4hart \
HELIODOR_RUNNERS="veryl-cc-sync celox celox-tiered veryl-cc-tiered" \
HELIODOR_CELOX_CARGO_PROFILE=release HELIODOR_TIMEOUT_SEC=10800 \
bash scripts/run-heliodor-bench.sh run一部の構成だけを再実行する場合は、手動実行の suite_test、suite_runner、 suite_arch を指定します。空欄なら全構成が対象です。絞り込み実行では gate を実行しません。master 上の手動実行は成功した結果から 個別に公開し、他のブランチの結果は公開しません。例:
gh workflow run heliodor-bench.yml --ref <branch> \
-f suite_test=test_soc_66_smp_linux_boot_4hart \
-f suite_runner=celox -f suite_arch=aarch64nightly・手動実行とも、上のグループ分けを使います。一部だけを比較する場合は、 suite_runner にスペース区切りで指定すると、各グループ内でその順序に実行します。 選択したバックエンドが別グループに属する場合、グループは結合しません。 CPU 情報、ランナー名、グループ、run/attempt、boot ID を結果と一緒に保存します。 Veryl-CC の AOT-C キャッシュは各測定で新しく作成します。
gh workflow run heliodor-bench.yml --ref <branch> \
-f suite_test=test_soc_66_smp_linux_boot_4hart \
-f suite_runner="celox-tiered veryl-cc-tiered" -f suite_arch=aarch64各グループの実行上限はビルドを含めて 5 時間 50 分です。 最長のバックエンド実行枠とは別に、checkout と Rust ビルドのために 20 分を確保し、 セットアップ・終了処理・成果物アップロード用に約 10 分を残します。 GitHub ホストジョブの 6 時間上限までにログを保存するためです。 時間切れやバックエンドの結果欠落は CI の失敗として扱います。 完走したバックエンドの結果は公開し、未完了の起動時間は公開しません。各バックエンドの個別上限もこの共通予算内で適用します。 別コミットを含む別 workflow run の履歴は、同一 CPU での比較ではありません。