perf_runner の設計

設計目標

moon bench は要約を報告します。一方、リポジトリのレポートパイプラインには、繰り返しとウォームアップを自前で制御した単一ケースの生のサンプルごとの計時と、ケースを再実行して結果を確認する手段が必要です。perf_runner はそのための単一ケース用ツールです。

数学的背景

サンプルは repeat 回の連続した呼び出しの平均時間 t=1repeat∑j=1repeatTjt = \tfrac1{\text{repeat}} \sum_{j=1}^{\text{repeat}} T_j です。サンプル内で平均をとることで、計測ごとに一定であるタイマー分解能の誤差は repeat 分の 1 に、呼び出しごとの独立なノイズは 1/repeat1/\sqrt{\text{repeat}} 倍に減ります。サンプル間では、パイプラインはスケジューリングによる外れ値に頑健な順序統計量(中央値、p90)と MAD を使います。ウォームアップの回は、最初の呼び出しの過渡的な影響(キャッシュ、分岐予測器、遅延初期化)を捨てます。

設計上の判断

タイマーの外でのスクラッチコピー

入力を変更するケースでは、repeat 個のコピーを monotonic_clock_start の 前に 準備するので、コピーは計測されず、どの呼び出しも同じ入力を受け取ります。

すべてのモードでのチェックサム

各呼び出しのチェックサムは累積値に畳み込まれるので、処理は観測可能なままであり、診断モードでは結果がビット単位で同一であることを検証できます。

素朴な JSON 行

出力は 1 回の実行につき 1 つの JSON オブジェクトで、文字列連結で組み立てます。これによりランナーはシリアライズ用の依存を持たずに済み、Python からも簡単に解析できます。

正しさと不変条件

  • 診断モードでは、出力されるチェックサムは呼び出しごとのチェックサムを FNV 風に畳み込んだものに等しく、パッケージのホワイトボックステストがそれを検証します。
  • スクラッチケース用に作るコピーが、準備済みの入力とエイリアスになることはありません。

却下した代替案

  • 呼び出しごとに個別に計時する。 1 マイクロ秒未満の呼び出しはクロックの分解能を下回ります。repeat はそれを償却します。

境界

ランナーはプロセスごとに 1 つのケースを計測し、自身では統計量を計算せず、perf_support に登録されたケースだけをサポートします。