perf_support の設計
設計目標
数値カーネルのベンチマークが役に立つのは、再現可能で比較可能な場合だけです。すなわち、どの実行・どのマシンでも同じ入力を使い、準備ではなく計算そのものを計測し、計測したコードが実際に実行されたことを保証する必要があります。perf_support は、このリポジトリのベンチマークサブシステムにそれらの保証を提供します。
数学的背景
決定的な入力
入力はケースごとのシードから SplitMix64 生成器で生成し、目的の分布(たとえば 上の一様分布)に写します。構造を持つ族は、そうした乱数から構成的に作ります。たとえば対称正定値行列を として作ります。 について なので、これは任意の について SPD です。同じシードからは常に同じビット列が得られるので、フィクスチャは保存せずに再生成できます。
チェックサム
各実行は、その結果のビットパターンを FNV 風の混合で 64 ビット値に畳み込みます。
ここで は 番目の出力値の IEEE ビットパターンです(行列では形状が先)。チェックサムには 2 つの目的があります。コンパイラが計算をデッドコードとして除去するのを防ぐことと、実行・ターゲット・バージョン間で結果のビットが変わったことを検出することです。暗号学的ハッシュではありません。
設計上の判断
フィクスチャは実行時、レジストリはコード
ケースの一覧は bench/datasets/manifest.json から MoonBit のコード(generated_registry.mbt)として生成され、大きな入力配列は実行時に読み込む JSON ファイルに置かれます。これによりベンチマークのバイナリが小さく保たれてコードサイズが計測を歪めず、Rust のベースラインも同じフィクスチャを利用できます。
自己修復するフィクスチャ
フィクスチャファイルがない場合は、レジストリのシードから再生成して書き出すので、クリーンなチェックアウトでもどのケースでも実行できます。ファイルが存在してもバージョン、メタデータ、形状がレジストリと一致しない場合は実行を中断します。食い違った入力を黙って使うと、数値が無意味になってしまうからです。
変更ポリシー
入力を変更する操作もあります(たとえば reduce_row_elimination)。そのため mutation_policy = "scratch_per_sample" のケースは新しいコピーに対して実行し、どのサンプルも同じ処理を計測するようにします。
検査なしカーネル
ベンチマークは unchecked_* メソッドを呼び出します。入力が前提条件を満たすことはわかっており、計測したいのは検証のコストではないからです。
正しさと不変条件
- データセットのバージョンを固定すれば、
prepare_case(c)はどの実行でもビット単位で同一の入力を生成します。 run_prepared_case_inplace(p, true)はpを変更しません。- チェックサムはすべての出力値と出力の形状に依存します。
却下した代替案
- すべての入力をコードに埋め込む。 大きなリテラル配列はバイナリとコンパイル時間を膨らませます。
- 実行ごとにランダムな入力。 実行間で結果を比較できなくなります。
境界
perf_support 自身は何も計測しません。計時と統計量は perf_runner、perf、bench/run.py にあります。対象は Double 入力の @mutable パッケージだけで、既定のテストゲートには含まれません。