Appearance
CPU 使用率指标 —— %usr、%sys、%idle、%iowait、%steal、%irq、%softirq
top第一行的%Cpu(s): 2.3 us, 1.0 sy, 0.0 ni, 96.0 id, 0.7 wa, 0.0 hi, 0.0 si, 0.0 st—— 这串数字是排查性能问题的第一眼。每个百分号后面的缩写分别代表什么?它们的数据源是哪里?为什么%iowait高不等于磁盘慢?本文逐一拆解。
更新时间:2026-08-06
一、八种 CPU 时间分类速览
内核把每个 CPU 核心在一个采样周期内消耗的时间按"正在做什么"分成八大类。这八个指标之和 = 100%(或接近 100%,考虑采样精度误差)。
| 缩写 | 全称 | 含义 | 典型触发场景 | 对应工具列名 |
|---|---|---|---|---|
| %usr | user | 用户态普通优先级进程占用 CPU | 业务代码计算、正则匹配、JSON 解析 | top:us、mpstat:%usr |
| %nice | nice | 用户态低优先级(nice > 0)进程占用 CPU | 后台批处理任务、renice 降低优先级的进程 | top:ni、mpstat:%nice |
| %sys | system | 内核态 CPU 时间 | 系统调用(syscall)、内核线程、中断下半部之外的内核逻辑 | top:sy、mpstat:%sys |
| %idle | idle | CPU 完全空闲,无事可做 | 系统负载低、无进程可调度 | top:id、mpstat:%idle |
| %iowait | iowait | CPU 空闲 + 存在 D 态进程等待块设备 I/O 完成 | 磁盘慢、Swap 换入换出、fsync 同步落盘 | top:wa、mpstat:%iowait |
| %irq | hardware IRQ | 处理硬件中断 | 网卡收发包中断、磁盘控制器中断、定时器中断 | top:hi、mpstat:%irq |
| %softirq | softirq | 软中断 / 中断下半部 | 网络收发包的 NAPI 处理、块设备 I/O 完成回调、定时器 | top:si、mpstat:%soft |
| %steal | steal | CPU 被宿主机(hypervisor)"偷走"的时间 | 虚拟机 CPU overcommit、宿主机资源争抢 | top:st、mpstat:%steal |
| %guest | guest | 运行虚拟机的客户机 OS 代码 | KVM / Xen 虚拟机中的 CPU 时间 | top:gu、mpstat:%guest |
注意:
%guest已经包含在%usr中,%guest_nice包含在%nice中。大多数场景不需要单独关注这两个。
二、数据源与计算公式
所有八类 CPU 时间的数据源都是 /proc/stat,每个 CPU 核心一行:
bash
$ cat /proc/stat | grep cpu0
cpu0 123456 789 23456 9876543 5678 0 345 0 0 0从左到右依次是(单位:jiffies,通常 CONFIG_HZ=250,即每 jiffy = 4ms):
| 位置 | 字段名 | 对应指标 |
|---|---|---|
| 1 | user | 用户态普通进程 CPU 时间 |
| 2 | nice | 用户态 niced 进程 CPU 时间 |
| 3 | system | 内核态 CPU 时间 |
| 4 | idle | 空闲时间 |
| 5 | iowait | I/O 等待时间 |
| 6 | irq | 硬中断时间 |
| 7 | softirq | 软中断时间 |
| 8 | steal | 被虚拟化偷走的时间 |
| 9 | guest | 运行虚拟机客户机的时间 |
| 10 | guest_nice | 运行 niced 虚拟机客户机的时间 |
计算公式(以 %usr 为例):
总时间增量 = (user2 - user1) + (nice2 - nice1) + ... + (guest_nice2 - guest_nice1)
%usr = (user2 - user1) / 总时间增量 × 100关键认知:
top、vmstat、mpstat等工具自己实现了这套"两次采样取差值 → 除以总时间 → 转百分比"的计算逻辑。内核只提供 jiffies 原始累计值,不计算百分比。
三、指标逐个详解
3.1 %usr(用户态 CPU)——"业务代码在跑"
- 统计内容:进程在用户态(Ring 3)执行指令消耗的 CPU 时间。
- 告诉你什么:应用程序的计算密集型程度。高
%usr= 业务逻辑计算量大,排查方向是优化算法、减少循环、缓存计算结果。 - 不包含:系统调用(哪怕是你自己写的
read()/write()→ 计入%sys)。 - 需要注意:单核 100%
%usr可能正常(计算密集型任务),但如果是 web server 高%usr要排查:是否有死循环?Regex 是否回溯爆炸?JSON 序列化是否频繁?
3.2 %sys(内核态 CPU)——"内核在替你做事"
- 统计内容:内核态(Ring 0)消耗的 CPU 时间,包括系统调用处理、内核线程、中断下半部分之外的内核逻辑。
- 告诉你什么:系统调用的密度和开销。高
%sys= 要么系统调用频率极高(如频繁gettimeofday()),要么每个系统调用的处理逻辑很重(如大量mmap/munmap、fork)。 - 典型场景:
%sys>%usr:系统调用瓶颈——排查方向是减少系统调用、批量操作(readv/writev)、使用io_uring%sys伴随高%irq/%softirq:网络中断风暴
3.3 %idle(空闲)——"无事可做"
- 统计内容:CPU 没有可调度的进程、没有待处理中断、处于 halt 指令循环的时间。
- 告诉你什么:系统有多"闲"。
%idle接近 100% 说明系统负载很低;%idle接近 0 说明 CPU 是瓶颈。 - 注意:
%idle低不等于"系统有问题"——对于计算密集型应用,%idle=0且%usr≈100%是完全正常的。
3.4 %iowait(I/O 等待)——"CPU 想干活但磁盘拖后腿"
统计条件:必须同时满足两个条件:
- CPU 运行队列为空(没有 R 态进程等 CPU)
- 系统中至少有一个 D 态(不可中断睡眠)进程在等待块设备 I/O
最容易误解的指标:
%iowait=30%不等于 "磁盘 IO 占了 30% 的 CPU 时间"——而是"30% 的时间 CPU 想干活但没活可干,同时有人在等磁盘"%iowait=0%不等于 "磁盘没问题"——可能 CPU 正忙着跑 R 态进程,iodelay 已经涨上天了
详见 iowait.md 场景一和场景二的完整时序分析。
3.5 %irq / %softirq(中断开销)——"网卡在轰炸 CPU"
%irq(硬中断,hardware IRQ):
- 硬件设备(网卡、磁盘控制器、USB 控制器)触发的中断处理
- 高
%irq= 硬件中断频率过高,排查方向:- 网卡是否开启了中断合并(ethtool -C rx-usecs)
- 是否可以用轮询模式替代中断模式(NAPI 已自动处理大部分场景)
%softirq(软中断,softirq):
- 硬中断的下半部处理,把耗时操作推迟执行
- 网络收发包处理是最大的 softirq 来源(
NET_RX_SOFTIRQ、NET_TX_SOFTIRQ) - 高
%softirq= 网络包处理瓶颈,排查方向:- 查看
/proc/softirqs确认是哪个 CPU 核心的软中断高 - 使用 RSS(Receive Side Scaling,接收端缩放)把软中断分散到多个核心
- 详见 rss.md
- 查看
3.6 %steal(被偷走的时间)
- 仅虚拟化场景有意义:当宿主机 CPU overcommit 时,分配给本 VM 的 vCPU 被调度到其他物理 CPU 上等待
%steal> 0 意味着宿主机资源紧张,本 VM 在排队等 CPU- 物理机上
%steal永远为 0
四、多核场景下的理解
top 默认显示所有核心的聚合值(Irix mode off)。八个指标都是百分比,8 核机器上 %usr=200% 意味着全核心的 25% 被用户态占用。
查看每个核心:
bash
mpstat -P ALL 1 # 每个核心单独一行这是定位"某个核心被打满而其他核心空闲"(典型的软中断绑核问题)的关键命令。
五、常见排查模式速查
| 现象 | 可能的根因 | 下一步 |
|---|---|---|
%iowait 高 | 磁盘慢(瓶颈)或 CPU 空闲(正常) | iostat -x 1 看 await/util,pidstat -d 1 看 iodelay |
%sys 高 | 系统调用过多或内核逻辑重 | strace -c 统计系统调用频率和耗时,perf top 看内核热点函数 |
%usr 高、%idle=0 | CPU 计算瓶颈 | perf top 看用户态热点函数,perf record 做火焰图 |
%softirq 高 | 网络收发包瓶颈 | watch -d -n1 cat /proc/softirqs 确认,调整网卡多队列/RPS |
%steal > 5% | 虚拟机 CPU overcommit | 宿主机减少 VM 数量,或降低各 VM 的 vCPU 数 |
%irq 高 | 硬件中断频率过高 | watch -d -n1 cat /proc/interrupts 确认来源,调整中断合并 |
%iowait=0 但磁盘响应慢 | CPU 繁忙掩盖了 I/O 等待 | pidstat -d 1 直接看进程级 iodelay,不受 CPU 繁忙程度影响 |
六、一句话总结
%usr/%sys/%idle/%iowait/%irq/%softirq/%steal/%nice 八项指标将 CPU 时间按"正在做什么"做了分类,数据源是 /proc/stat 的 jiffies 累计值,百分比由用户态工具两次采样计算得出。其中 %iowait 最容易误判——它统计的是"CPU 空闲等待磁盘"而非"磁盘有多慢",CPU 繁忙时可降为零掩盖 I/O 瓶颈;%softirq 高标志着网络包处理压力,排查方向是中断分发策略。