# CPU Utilization is Wrong
[[Brendan Gregg]](2017 年当時 Netflix、現 Intel)が 2017 年 5 月に個人ブログで公開した短編記事。「%CPU は嘘をついている」というシンプルな主張を Linux `perf` の実測データで裏付けた、パフォーマンス界隈で広く引用される古典的エッセイ。
## 核心主張
`top(1)` や `ps(1)` が表示する **%CPU は「非アイドル時間の割合」**であり、CPU が何をしているかを教えない。具体的には:
- **演算(instruction retired)** に費やした時間
- **メモリ待機(memory stall)** に費やした時間
の合計が %CPU として表れる。現代の CPU は DRAM よりはるかに高速なため、「%CPU = 100%」のサーバーが実際は大半の時間をメモリ待機に費やしている可能性がある。
## 実測例
`perf stat -a sleep 10` で計測したシステム全体の統計:
```
10,002,771,605 cycles
8,047,896,226 stalled-cycles-frontend
6,272,034,740 stalled-cycles-backend
1,564,636,234 instructions # 0.16 insns per cycle
```
この例では IPC = 0.16。4-wide プロセッサで IPC = 0.78 なら最高速度の 19.5% しか発揮できていない計算になる。
## 正しいメトリクス: IPC(Instructions Per Cycle)
| IPC 値 | ボトルネック | 対処 |
|--------|-----------|------|
| **< 1.0** | メモリバウンド(DRAM 待機) | メモリ I/O 削減・キャッシュ改善・プリフェッチ最適化 |
| **≥ 1.0** | 命令バウンド | 命令数削減・アルゴリズム改善 |
## %CPU が誤解を招くその他の要因
1. **サーマルスロットリング**: 発熱時に CPU クロックが下がる → 同じ %CPU でも仕事量が減る
2. **可変クロック(Turboboost / SpeedStep / P-state)**: 「1 サイクル」の時間が変動する
3. **スピンロック**: ビジーウェイトは %CPU を消費するが論理的な仕事ゼロ
4. **分単位の平均**: 1 分中 1 秒間 100% → 1 分平均 ~1.7% に埋没
## CPU-DRAM ギャップ
過去数十年で CPU の演算速度は飛躍的に向上したが、DRAM 帯域幅はそれに追いつかなかった。このギャップにより、現代のワークロードはかつてより遙かにメモリバウンドになっており、%CPU の誤解を招く度合いも増している。
## 測定方法
```bash
# システム全体(10 秒間)
perf stat -a sleep 10
# プロセス単位
perf stat -e cycles,instructions,cache-misses,cache-references -p <PID>
```
重要カウンタ: `cycles`、`instructions`、`stalled-cycles-frontend`、`stalled-cycles-backend`
## 推奨事項
パフォーマンス監視ツールは %CPU に加えて以下のいずれかを表示すべきとする:
- IPC(サイクルあたり命令数)
- サイクルの内訳(命令消化 / メモリストール / その他ストール)
## 関連
- エンティティ: [[Brendan Gregg]]
- 概念: [[CPU利用率]] / [[Instructions Per Cycle]] / [[ハードウェアカウンタ]] / [[メモリバウンド]]
- 概念(IPC 名称混同注意): [[IPCメトリクス]] は「プロセス間通信メトリクス」であり本記事の IPC(Instructions Per Cycle)とは別概念
## 出典
- 原文: https://www.brendangregg.com/blog/2017-05-09/cpu-utilization-is-wrong.html