ブラウザの CPU 負荷テストは何を測れるのか。Web Worker で作って、4コア機で実測した
TL;DR
- ブラウザだけで CPU に負荷をかけるツールを作っています。中身は Web Worker で計算ループを回し、1秒ごとにスコアを記録するだけです
- 4コア4スレッドの機械で、ワーカー数を 1/2/4/8 に変えて測ると、4本が最大で、8本は4本の約6割に落ちました(コア数を超えると逆効果)
- 途中で外部から CPU を奪うと、スコアは約半分になり「性能低下」の警告が出ます。ただしこの警告は、熱による低下なのか、他のプロセスとの競合なのかを区別できません
- 負荷をかける前にも、揺らぎだけで警告が出ました。これを受けて、ツールを3点直しました(ワーカー数の上限、警告の文面、警告の判定方法)。直した後も、普段使いのデスクトップでは負荷なしで警告が出ることがあります。その限界まで書きます
作ったもの
仕組みは3つだけです。
-
navigator.hardwareConcurrencyの数だけ Web Worker を起動する - 各 Worker が計算ループを回し、200ms ごとに「その間の演算回数」を
postMessageする - メインスレッドが全 Worker の値を合計し、1秒ごとに履歴へ積む
Worker の中身はこれだけです。
let ops = 0;
let lastReport = performance.now();
while (true) {
for (let i = 0; i < 20000; i++) {
ops += Math.sqrt((i + 1) * 1.0000001) % 7;
}
const now = performance.now();
if (now - lastReport >= 200) {
postMessage(ops); // 200ms 分の演算回数
ops = 0;
lastReport = now;
}
}
画面のスコアは、直近200msの合計を5倍して「pt/秒」にしたものです。
性能低下の検知は、最初は次の単純なものでした。履歴が15点以上たまったあと、1秒ごとの値のピークと直近の値を比べ、15%以上下がっていたら警告します。(この記事で測った結果を受けて、あとで直しました。「ツールを直した」の節を参照)
実測1: ワーカー数を変えるとスコアはどうなるか
環境は Intel Core i3-9100(4コア4スレッド)です。ブラウザは Playwright 同梱の Chromium(ヘッドレス)を使いました。ワーカー数ごとに12秒実行し、結果カードの「総合スコア」を読んでいます。
| ワーカー数 | 総合スコア(pt/秒) | 1本の場合との比 | ワーカー1本あたり |
|---|---|---|---|
| 1 | 203,185,703 | 1.00倍 | 203,185,703 |
| 2 | 388,291,464 | 1.91倍 | 194,145,732 |
| 4 | 604,779,921 | 2.98倍 | 151,194,980 |
| 8 | 364,403,470 | 1.79倍 | 45,550,434 |
分かることは3つあります。
- 1→2本はほぼ2倍に伸びますが、4本では3倍弱です。4本のときは、ブラウザ本体など他のプロセスも同じ CPU を使うため、純粋な4倍にはなりません(内訳は測っていません)
- 8本にすると、4本のときの約60%(364M / 605M)まで落ちました。 論理コアより多くのスレッドを回しても、合計は増えず、むしろ減りました
- ワーカー1本あたりのスコアは、本数が増えるほど下がります。「ワーカー1つあたり平均」は、コア単体の性能として読めません
なお、このツールのスライダーは、既定値が論理コア数で、上限が論理コア数の2倍です。上限まで上げると、この結果のとおり合計スコアは下がります。
原因は切り分けていません。コア数を超えたスレッドの奪い合い(コンテキストスイッチ)が主な理由だと考えていますが、測っていないので推測です。
実測2: 途中で他の処理を走らせると、警告は出るのか
4本で測定を始め、20秒の時点で、別のシェルからビジーループを4プロセス起動しました(while :; do :; done)。Worker 4本と合わせて8本分の計算が、4コアを取り合う形です。
- 外部負荷の前: 5.4〜5.9億 pt/秒前後
- 外部負荷の後: 3億前後(2.6〜3.9億の範囲)。ピーク比で約50%の低下
- 警告: 起動の1秒後(21秒)に表示され、以降ずっと出続けました
警告の文面は次のとおりです。
性能低下を検出しました(ピーク比 49% 低下)。… サーマルスロットリングや電源(電力制御)の介入などにより処理能力が低下している可能性があります。
今回、原因は完全に CPU の競合で、熱は関係ありません。 それでも警告は「サーマルスロットリングなどの可能性」と出ます。ツールの使い方のページには「他アプリの動作でも発生する」と書いていますが、警告の文面だけを見た人には区別がつきません。ブラウザからは CPU の温度もクロックも見えないので、警告は「低下した」ことを示すだけで、原因までは分かりません。
負荷なしでも警告が出ることがある
外部負荷をかける前の19秒の時点で、すでに警告が1回出ていました。
ピーク時 660,409,944 → 直近 539,381,427(ピーク比 18% 低下)
この時点では何も走らせていません。履歴上のピーク値と直近の値の差だけで、15%のしきい値を超えました。そこで、何も走らせない状態で60秒の測定を3回行い、揺らぎの大きさを調べました(1秒ごとのスコアを記録し、あとから計算しています)。
| 比べる単位 | 3回それぞれの「ピークからの最大低下率」 |
|---|---|
| 1秒ごとの値 | 44% / 56% / 40% |
| 5秒平均 | 22% / 36% / 20% |
| 10秒平均 | 18% / 25% / 10% |
何も起きていなくても、スコアは1秒単位では半分近く揺れ、10秒平均にしても最大25%の低下に見えます。測定は普段使いのデスクトップ(デスクトップ環境などが動いている状態)で行ったので、静かな専用機ならもっと小さいはずです。それでも、「15%下がったら警告」は、揺らぎに対して厳しすぎました。
ツールを直した
実測の結果を受けて、ツールを3点直しました(日本語版・英語版とも)。
- ワーカー数の上限を、論理コア数に変更した: これまでは論理コア数の2倍まで上げられましたが、上げるほど合計スコアが下がるだけでした。スライダーの下に、その旨の説明も追加しました
- 警告の文面を、原因を断定しない書き方に変えた: 「サーマルスロットリングの可能性」だけだった文面を、「このツールでは原因を特定できません。熱・電源制御のほか、他のアプリやタブとの競合でも同じ表示になります。タスクマネージャーなどで他の処理を、温度モニターで温度を確認してください」に変更しました
- 警告の判定を、1秒ごとの値から10秒平均に変えた: 比べる対象を「ピークの10秒平均」と「直近10秒の平均」にし、しきい値を20%、判定の開始を30秒以降にしました。1点の揺らぎで警告が出ることは、これでなくなります
直した後に、同じ実験をもう一度行いました。
- スライダーの上限: この機械では4(論理コア数)になりました
- 外部から4プロセスの負荷をかけた場合: 警告は負荷の2〜4秒後に出ました(ピーク比21%低下)
- 何も走らせない場合: 直したあとでも、日本語版の30秒付近(32%低下)と、英語版の60秒付近(24%低下)で警告が出ました。 この機械では、10秒平均でも25〜32%程度は揺れるようです
しきい値を、この機械の揺らぎに合わせて緩めることはしませんでした。緩めると、本物のサーマルスロットリングを見逃すからです。代わりに、警告は「低下した」ことの合図であり、原因の診断ではないと文面で明示しました。長く測定して、グラフの後半が前半より下がり続けているかを見るのが、いちばん確かです。
測れないもの
実測してはっきりしたことを、先に書いておきます。
- 絶対性能の比較には使えません。 スコアは、ブラウザ・OS・同時に動く処理に依存します。使えるのは「同じ環境での前後の変化」と「複数台の相対比較」までです
- 温度とクロックは見えません。 熱による低下かどうかは、このツールでは断定できません。OS 側のモニタ(HWiNFO など)と併用するのが確実です
- バックグラウンドのタブは、ブラウザが処理を抑えることがあります。 測定中はタブを表示したままにしてください
- GPU テスト(WebGL でマンデルブロ集合を描画して FPS を測る)は、今回の実験では測っていません。 この記事の数値は CPU だけです
まとめ
- ブラウザの Web Worker でも、コア数に応じたスコアの伸びは見えます。ただしワーカー数を論理コア数より増やすと、合計は下がります
- 「性能低下」の警告は、熱・電源・他のプロセスとの競合を区別できません。出たら、温度モニターなど別の手段で切り分けてください
- 負荷なしでもスコアは1秒単位で半分近く揺れます。実測をもとに、ワーカー数の上限・警告の文面・判定方法(10秒平均、20%、30秒以降)を直しました。それでも普段使いのPCでは、負荷なしで警告が出ることがあります
ツールはこちらです。インストール不要で、入力もサーバーには送りません。
https://meowassist.net/tools/cpu_gpu_stress_test.php
長時間の測定は、発熱とバッテリー消費が増えます。異常を感じたら、すぐに停止してください。