Windows上でプログラムの実行速度を正しく比較する

· · Windows, Benchmark, Performance, Profiling, Power Management

まず結論

再現性のあるベンチマークを取るための6つのポイント:

  1. 「何を比較したいか」を先に決める: コード差を見たいのか、実ユーザー体験を見たいのか
  2. power mode と power plan を別物として記録する
  3. 冷えた1回目と温まった後の定常状態を分ける
  4. A→B→A→B のように交互に回す
  5. 平均だけでなく中央値とばらつきを見る
  6. 差が小さいなら ETW/WPR で原因まで掘る

比較の種類を最初に決める

コード差を見たい比較

アルゴリズム変更やコンパイラ最適化など、実装そのものの差を知りたい場合。環境ノイズを可能な限り削る(clean boot、power mode 固定、通知停止など)。

実ユーザー体験を見たい比較

配布後にユーザーが実際に体感する速さを知りたい場合。ノイズを消してはいけない。OneDrive 同期、Defender、通知などを含めた日常環境で比較する。

この2つを混ぜると結論がねじれる(「ラボでは12%速いのに現実では誤差」など)。

結果がぶれる主な要因

ぶれ要因 典型例
ハードウェア CPU/GPU、メモリ、SSD、冷却 ノート PC の薄さ、冷却台の有無
ファームウェア BIOS/UEFI、OEM 制御 省電力ポリシー、ファン制御
OS Windows build、ドライバ、更新状態 更新後に挙動が変わる
電源 AC/DC、power mode、power plan バッテリー駆動だと別世界
室温、ファン、直前の負荷 1回目だけターボ、後半で失速
バックグラウンド Update、Defender、同期、通知 実行中にスキャンや同期が走る
データ/キャッシュ OS キャッシュ、アプリキャッシュ 初回だけ遅い、2回目以降だけ速い

power mode と power plan を固定する

この2つは別物

  • Power mode: 設定アプリの「システム > 電源とバッテリー」から選ぶ(Best power efficiency / Balanced / Best performance)
  • Power plan: 従来の電源プラン(Balanced / High performance など)。powercfg で確認

固定手順

  1. ノート PC は必ず AC 接続で比較する
  2. Power mode を固定する(ベンチ用途なら Best performance)
  3. Active power plan を記録する:
powercfg /list
powercfg /getactivescheme
  1. 必要なら High performance に切り替え:
REM High performance
powercfg /setactive 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c

注意点

  • Modern Standby 対応デバイスでは High performance が表示されないことがある(機種の設計上の制限)
  • Power mode が変更できない場合は、custom power plan が選択されている可能性あり。まず Balanced を選んでみる

バックグラウンドノイズを潰す

  1. 再起動して数分待つ: 起動直後は更新、インデックス、同期、Defender が暴れている
  2. 本格的な比較なら clean boot: msconfig で Microsoft 以外のサービスを停止。コード差を見るラボ比較向け
  3. 通知を切る: Do not disturb を有効にする
  4. 検索インデックスと同期を抑える: ベンチ用ディレクトリを検索対象から外す。OneDrive/Dropbox を止める。ブラウザや Teams を閉じる

熱を揃える

CPU/GPU は冷えている時と温まった後で別物。特にノート PC は顕著。

  • 室温を揃える
  • ノート PC の置き方を固定
  • AC アダプタ、ドック、外部ディスプレイ構成を固定
  • ベンチ前に重い作業をしない
  • 初回実行と定常状態を分けて測る

実行順序は交互にする

A を10回やってから B を10回 → NG(熱とキャッシュの偏りが載る)

おすすめ:

  • A B A B A B ...
  • A B B A A B B A ...
  • ランダム順序を事前生成して回す

何を測るか

指標 取得方法 用途
Wall-clock time(実時間) QueryPerformanceCounter / Stopwatch ユーザー体感に一番近い
CPU time(ユーザー+カーネル) GetProcessTimes 計算効率を見る
Cycle count QueryProcessCycleTime 待ち時間以外の計算負荷を見る

指標の組み合わせで読む

  • wall-clock だけ速い → I/O、待ち時間、キャッシュの改善かも
  • CPU time も cycle も下がっている → 実装そのものが軽くなった
  • 1回目だけ遅い/速い → cold/warm の差(起動、初期化、JIT)
  • 回を重ねるほど遅くなる → 熱、スロットリング、メモリ圧迫

priority、affinity は最後の手段

デフォルト状態で差が出るなら、その差自体に価値がある。最初から /high/affinity を入れると実際の Windows では起きない条件を持ち込むことになる。

start "" /high /wait myapp.exe --bench case1.json
start "" /affinity F /high /wait myapp.exe --bench case1.json

/realtime は使わない。 ノイズ除去ではなく別の事故を作る。

実践的な測定手順

  1. 比較対象を固定(commit hash、build number、Debug/Release、ログ有無)
  2. マシン条件を固定(Windows build、BIOS version、AC 接続、室温)
  3. 電源条件を固定(Power mode、Active power plan を記録)
  4. 再起動し、数分待つ
  5. 必要なら clean boot
  6. warm-up を入れる
  7. A/B を交互に回す(十分な回数を確保)
  8. 中央値・最小・最大・p95 を残す
  9. raw data を保存する
  10. 差が小さければ ETW/WPR を取る

記録すべき項目

timestamp, version, scenario, elapsed_ms, user_ms, kernel_ms, cycles,
power_mode, power_plan, ac_or_dc, room_temp_c, notes

可能なら:

cpu_package_temp_start_c, cpu_package_temp_end_c,
affinity_mask, priority_class, windows_build, driver_version

ETW/WPR で「なぜ速いか」まで掘る

差が小さい、または理由が読めないときは ETW(Event Tracing for Windows)へ。

wpr -start CPU -filemode
REM ここでベンチを実行
wpr -stop trace.etl

これで「B は lock 待ちが減って ready time が下がっている」「A は file open が増えて cold start が遅い」といった理由付きで議論できるようになる。

まとめ

Windows でバージョン比較をするときに本当に効くのは地味だが再現性に効く作法:

  • AC / Power mode / power plan を固定して記録
  • cold と warm を分ける
  • A / B を交互に回す
  • 中央値と分布を見る
  • 必要なら clean boot
  • 差が小さければ ETW/WPR で理由まで掘る

一番大事なのは、何を固定し、何を固定しなかったかを結果と一緒に書くこと。 条件の書かれていないベンチ結果は再現性の面で頼りない。

参考資料

関連する記事

同じタグを共有する最新の記事です。さらに近い話題で知識を深められます。

関連トピック

このテーマと近いトピックページです。記事を起点に、関連するサービスや他の記事へ進めます。

このテーマがつながるサービス

この記事は次のサービスページにつながります。近い入口からご覧ください。

ブログ一覧に戻る