mpstat —— 按 CPU 核心拆分利用率与中断分布
这个工具是做什么的
sysstat 套件成员。top 顶部的 %Cpu(s) 是所有核的平均,会把"单核跑满、其余空闲"平均成看似不高的占用。mpstat 能逐核看,专门回答"负载是均匀分布,还是压在某一个核上",以及"中断/软中断集中在哪个核"。
可以回答什么问题
| 问题 | 怎么用 |
|---|---|
| 所有核的负载是均匀的还是压在单核上? | mpstat -P ALL 1 逐核对比 %usr |
| 软中断集中在哪个核?是不是 CPU0? | -P ALL 看 %soft 列,集中在单核 = 网卡没开多队列 |
| 硬中断在哪个核处理? | -P ALL 看 %irq 列 |
| 具体哪种中断最频繁?分布在哪些核? | mpstat -I CPU 1 看每种中断的每秒次数和核分布 |
| 云主机 CPU 有没有被其他租户偷? | %steal 非零 = 宿主超卖 |
| 中断风暴了没有?打在哪个核? | mpstat -I SUM 1 看每核中断总次数 |
mpstat 能观测到的所有指标
mpstat 提供三种维度的输出,分别回答三类问题:
维度一:CPU 利用率(默认模式 / -P ALL)
| 指标 | 含义 | 回答的问题 |
|---|---|---|
%usr | 用户态 CPU 占用 | 业务代码在跑吗 |
%nice | 被 nice 调过优先级的用户态 | 有低优先级任务在抢 CPU 吗 |
%sys | 内核态占用(不含中断处理) | 系统调用/内核逻辑开销大吗 |
%iowait | 空闲且有 IO 未完成 | IO 是瓶颈吗 |
%irq | 硬中断处理占用 | 硬件中断在哪个核上跑 |
%soft | 软中断处理占用 | 网络/块设备下半部在哪处理 |
%steal | 被 hypervisor 偷走的时间 | 云主机被超卖了吗 |
%guest | 运行 vCPU 的时间 | 宿主机上虚拟机跑了多久 |
%idle | 真正的空闲 | 还有多少余量 |
维度二:中断汇总(-I SUM)
每个 CPU 核的中断总次数/秒,不区分中断号,适合快速定位"中断风暴打在哪个核上"。
维度三:中断明细(-I CPU)
按中断号/中断名称,逐核列出每种中断的每秒次数。这是 mpstat 最深层的观测能力——能精确到"IRQ 12 在 CPU0 上每秒触发 47 次",适合分析:
- 哪个硬件设备中断最频繁
- 设备的 MSI/MSI-X 中断向量分布在哪些核上
- 内核 IPI(核间中断)频率是否过高(RES/CAL/TLB 异常高说明跨核调度或 TLB shootdown 过多)
- 本地定时器中断(LOC/s)频率,间接反映内核 CONFIG_HZ
- 硬件是否产生 MCE(机器检查异常)
数据来源
- 来源文件:逐核 CPU 取自
/proc/stat(cpu0/cpu1… 每行各自的 jiffies 分类);每核中断/软中断取自/proc/interrupts与/proc/softirqs。 - 采集方式:按间隔读两次这些文件,对每个核分别做差算出百分比或速率。
- 由此决定的特性:
mpstat的逐核数据来自内核已经分好的 per-cpu 统计,所以能精确回答"负载压在哪个核""软中断集中在哪个核"——这是只看整机平均的 top/vmstat 给不出的。
yum install sysstat / apt install sysstat一、用法
# --- CPU 利用率 ---
mpstat # 只输出一次开机以来的平均(参考意义小)
mpstat 1 # 整机平均,每 1 秒刷新
mpstat 1 5 # 每秒一次,共 5 次
mpstat -P ALL 1 # 每个逻辑核分别一行 + 平均行(最常用)
mpstat -P 0 1 # 只看 0 号核
mpstat -P 0,3 1 # 只看 0、3 号核
# --- 中断统计 ---
mpstat -I SUM 1 # 每核的中断总次数/秒(不区分中断号)
mpstat -I CPU 1 # 每核按中断号/中断名称明细(最能定位中断问题)
mpstat -I ALL 1 # SUM + CPU 一起出
mpstat -I XALL 1 # 加软中断统计
mpstat -P ALL -I CPU 1 # CPU 利用率 + 中断明细同时输出二、CPU 利用率输出样例
15:30:01 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %idle
15:30:02 all 12.53 0.00 3.14 0.25 0.00 0.50 0.00 0.00 83.58
15:30:02 0 99.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00
15:30:02 1 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 99.00
15:30:02 2 0.99 0.00 0.99 0.00 0.00 0.00 0.00 0.00 98.02
15:30:02 3 2.00 0.00 1.00 1.00 0.00 2.00 0.00 0.00 94.00all 行是平均(等于 top 看到的),下面每一行是一个逻辑核。上面这个例子:0 号核 %usr 99% 被打满,其余核几乎空闲——典型的单线程瓶颈。
三、CPU 利用率字段解读(含义同 top 的 %Cpu 行,但精确到每核)
| 字段 | 含义 | 判读 |
|---|---|---|
%usr | 用户态 | 业务计算 |
%nice | 被 nice 调过优先级的用户态 | |
%sys | 内核态(不含中断,这点和 top 略有区别) | 系统调用、内核逻辑 |
%iowait | 该核空闲且在等 IO | 高 = IO 瓶颈 |
%irq | 硬中断占用 | 硬件中断处理 |
%soft | 软中断 | 网络收发主要在这里,网卡风暴时某核爆高 |
%steal | 被 hypervisor 偷走 | 云主机超卖时出现 |
%guest | 运行 vCPU 的时间 | 宿主机才有 |
%idle | 空闲 | 越低越忙 |
四、典型判断
- 单线程瓶颈:
-P ALL下只有一个核%usr高、其余空闲 → 加核无用,得优化算法或改成多线程/多进程并行。 - 负载均匀:各核
%usr差不多 → 已经较好地利用了多核。 - 软中断集中在 CPU0:
%soft只在 0 号核高 → 网卡没开多队列(RSS)或没配 RPS/RFS,网络中断全压一个核。解决:开网卡多队列、配置/proc/irq/*/smp_affinity或 RPS 把中断分散到多核。 - 某核
%steal高:云环境宿主超卖,同宿主的其他租户在抢 CPU,和你的代码无关。 %iowait高但只集中某核:该核上的进程在做同步 IO,转 iostat/iotop 查。
五、中断统计观测(-I CPU 深度分析)
mpstat -I CPU 1 是定位中断分布问题的利器。它能列出每种中断在每核上的每秒触发次数——从硬件 IRQ 到内核 IPI(核间中断)一览无余。
5.1 输出样例
以下是一台 4 核 CentOS 7(3.10 内核)的实际输出(仅截取两个周期的部分行):
Linux 3.10.0-1160.108.1.el7.x86_64 07/12/26 _x86_64_ (4 CPU)
15:43:07 CPU 0/s ... 12/s 24/s ... LOC/s IWI/s RES/s CAL/s TLB/s ...
15:43:08 0 0.00 ... 47.00 0.00 ... 154.00 3.00 57.00 0.00 3.00 ...
15:43:08 1 0.00 ... 0.00 0.00 ... 175.00 1.00 87.00 8.00 4.00 ...
15:43:08 2 0.00 ... 0.00 0.00 ... 160.00 4.00 111.00 0.00 2.00 ...
15:43:08 3 0.00 ... 0.00 0.00 ... 158.00 1.00 34.00 0.00 2.00 ...5.2 字段详解:所有中断列的含义
-I CPU 输出的列头分三类:传统 IRQ 编号、MSI/MSI-X 中断号、命名中断(内核 IPI 和特殊中断)。下面逐一解释。
传统 IRQ 编号(0-15,8259 PIC 时代的遗产)
| 列头 | 对应中断 | 典型设备 | 说明 |
|---|---|---|---|
0/s | IRQ 0 | 系统定时器(PIT/HPET) | 传统定时器,现代系统多用 LOC 替代,通常为 0 或极低 |
1/s | IRQ 1 | 键盘控制器 | 物理机键盘中断,云主机通常为 0 |
4/s | IRQ 4 | 串口 ttyS0 | 有串口设备才非零 |
6/s | IRQ 6 | 软盘控制器 | 现代系统基本为 0 |
8/s | IRQ 8 | RTC 实时时钟 | 周期性时钟,一般很低 |
9/s | IRQ 9 | ACPI | 电源管理相关 |
11/s | IRQ 11 | 其他设备 | 可能被 PCI 设备共享 |
12/s | IRQ 12 | PS/2 鼠标(或 PCI 设备) | 云主机上如果非零,通常是 virtio 或存储控制器 |
14/s | IRQ 14 | IDE 主通道 | 使用 IDE 磁盘时出现,现在少见 |
15/s | IRQ 15 | IDE 从通道 | 同上 |
传统 IRQ 在现代系统上大部分为 0。如果某个编号持续非零,说明有设备没有用 MSI/MSI-X,路由到了传统中断线上——通常去找
/proc/interrupts确认具体设备。
MSI/MSI-X 中断号(24 以上)
| 列头 | 含义 | 说明 |
|---|---|---|
24/s, 25/s, ... | PCI 设备的 MSI/MSI-X 中断向量 | 每个设备的中断向量号由内核动态分配,具体对应哪个设备需查看 /proc/interrupts。网卡多队列会分配多个连续向量号(每个队列一个) |
命名中断(内核 IPI 和特殊中断)
这是 -I CPU 最有价值的部分——能看到内核内部的核间通信频率。
| 列头 | 全称 | 含义 | 判读 |
|---|---|---|---|
NMI/s | Non-Maskable Interrupt | 不可屏蔽中断 | 硬件严重错误(内存 ECC、PCI 奇偶校验)时触发。持续非零 = 硬件故障,需立即排查 |
LOC/s | Local Timer Interrupts | 本地 APIC 定时器中断 | 这是每个核的调度时钟中断源。频率由内核 CONFIG_HZ 决定(100/250/300/1000)。每个核每周期一次,所以约为 HZ 值。是现代系统上唯一的"规律性"中断 |
SPU/s | Spurious Interrupt | 虚假中断 | 属于噪声,少量无害。持续增高可能是硬件 APIC 问题 |
PMI/s | Performance Monitoring Interrupt | 性能监控中断 | perf、oprofile 等工具使用 PMU 采样时触发。不用 perf 时为 0 |
IWI/s | IRQ Work Interrupt | IRQ 工作队列中断 | 中断上下文中的部分工作需要延迟到进程上下文执行时,通过触发 IWI 来调度。伴随网络/磁盘高 IO 时出现,正常现象 |
RTR/s | — | 架构相关(x86 上通常为 0) | 非零时查阅具体内核版本的中断类型定义 |
RES/s | Rescheduling Interrupts | 重新调度 IPI(核间中断) | 跨核唤醒 task 时触发。当 CPU A 上的进程唤醒 CPU B 上睡眠的任务时,A 向 B 发 RES IPI 让 B 立即检查是否需要重新调度。值高 = 跨核唤醒频繁,常见于多线程应用或负载均衡活跃时 |
CAL/s | Function Call Interrupts | 函数调用 IPI | 一个核要求另一个核执行某函数时触发(如 smp_call_function())。值高 = 跨核同步操作频繁(如 RCU 回调、tlb flush 广播) |
TLB/s | TLB Shootdown Interrupts | TLB 刷新 IPI | 进程切换时,若新旧进程不同 mm(不同地址空间),需要通知所有跑过该进程的核刷新 TLB。多线程应用间值低(同 mm 不刷),频繁 fork/exec 或不同进程间切换多时值高 |
TRM/s | Thermal Event Interrupts | 温度事件中断 | CPU 过热降频时触发。非零 = 散热有问题 |
THR/s | Threshold Interrupts | MCA 阈值中断 | 可纠正错误的累积计数达到阈值时触发。非零需结合 mcelog 分析 |
DFR/s | Deferred Error Interrupts | 延迟错误中断 | 硬件错误延迟报告 |
MCE/s | Machine Check Exception | 机器检查异常 | 致命硬件错误(内存不可纠正错误、总线错误)。非零必须立即停机排查 |
MCP/s | Machine Check Poll | 机器检查轮询(已纠正) | 已纠正的硬件错误通过轮询上报。少量可接受,持续增多说明硬件劣化 |
ERR/s | Error APIC Interrupt | APIC 错误中断 | APIC 内部错误 |
MIS/s | Miscellaneous | 杂项中断 | 架构相关,通常为 0 |
PIN/s | Posted Interrupt Notification | Posted 中断通知(虚拟化) | 虚拟化环境专用:vCPU 被抢占时,hypervisor 通过 posted interrupt 通知 guest |
NPI/s | Non-Posted Interrupt | 非 Posted 中断 | 虚拟化相关 |
PIW/s | Posted Interrupt Wakeup | Posted 中断唤醒 | 虚拟化相关 |
5.3 对以上样例数据的逐项分析
| 指标 | 观测值 | 解读 |
|---|---|---|
LOC/s | 每核 100~216/s | 正常。说明内核可能是 CONFIG_HZ=100 或 250,加上 nohz 关闭时额外 tick。4 核合计约 600~750 LOC/s,完全在正常范围 |
RES/s | CPU0: 44~194, CPU1: 33~173, CPU2: 47~111, CPU3: 25~76 | 偏高。RES 是跨核唤醒产生的 IPI。>100/s 说明跨核调度活跃——某核上的 IO 完成中断唤醒另一个核上睡眠的 task。也包含负载均衡的迁移通知。如果伴随 %sys 也高,需检查是否不必要的跨核竞争 |
IWI/s | 每核 1~5/s | 正常。IRQ 的延迟工作很轻 |
TLB/s | CPU1: 2~8, CPU0: 0~6 | 正常低值。说明当前运行的线程多数处于同一进程(同 mm),TLB 刷新不频繁。如果 >100/s 说明进程切换频繁且跨进程 |
IRQ 12/s | 仅在 CPU0 上出现 6~47/s | 设备中断绑定在 CPU0 上。可能是 virtio 存储控制器或网卡的单队列中断。需查看 /proc/interrupts 第 12 行确认设备。如果 %irq 也随之增高,建议配置 smp_affinity 或开启多队列把中断分散 |
IRQ 24~30/s | 偶有 CPU2 上 5~10/s | PCI 设备 MSI 中断,频率很低,无关紧要 |
| 传统 IRQ | 大部分为 0 | 正常。现代系统设备多数走 MSI/MSI-X |
关键判断:这台机器的中断画像整体健康。LOC/s 是正常的调度时钟,RES/s 偏高但未到告警级别。唯一值得关注的是 IRQ 12 只绑在 CPU0——如果这个设备的 IO 量很大,可以考虑分散到其他核。
5.4 中断分析的典型判断
LOC/s在所有核上稳定且相等 → 正常,这是调度时钟RES/s持续 >500/s → 跨核唤醒过于频繁,检查是否有不必要的锁竞争或过多的线程间通知TLB/s持续 >200/s → 大量跨进程切换(fork/exec 频繁),TLB 刷新开销不可忽略- 某个 MSI 向量号只在 CPU0 上非零 → 设备中断没做分散,网络/存储密集时 CPU0 会成为瓶颈
MCE/s或MCP/s非零 → 硬件告警,立即查 dmesg 和mcelogPMI/s非零但没开 perf → 有监控 agent 在后台采样,可能需要关闭或调整
六、常见排查方法与分析
6.1 软中断集中在 CPU0
现象:mpstat -P ALL 1 下 CPU0 的 %soft 很高,其余核接近 0。
根因:网卡未开多队列(RSS),或 RPS/RFS 未配置,所有网络中断的处理(softirq NET_RX)默认路由到 CPU0。
排查链:
mpstat -P ALL 1 → 确认 %soft 集中在单核
→ cat /proc/interrupts | grep <网卡名> → 看各队列中断是否分散到多核
→ ethtool -l <网卡> → 看 Combined/RX 队列数
→ 若只有 1 个队列 → ethtool -L <网卡> combined N(N ≤ CPU 核数)
→ 若不支持多队列 → 开启 RPS: echo <CPU掩码> > /sys/class/net/<iface>/queues/rx-0/rps_cpus6.2 负载压在单核
现象:-P ALL 下只有一个核 %usr 接近 100%,其余核 %idle > 90%。
结论:单线程计算密集型任务,加 CPU 核数无意义。应并行化算法(多线程/多进程),或 taskset 绑核避免缓存变冷。
6.3 云主机 CPU 被偷
现象:%steal 持续 > 5%,且 %usr + %sys 不高但应用响应变慢。
根因:宿主机 CPU 超卖,hypervisor 把你的 vCPU 时间给了其他租户。
处理:向云平台提工单、迁移到不超卖的实例类型、或改用裸金属。
6.4 iowait 高
现象:某些核 %iowait 持续 > 20%。
排查链:
mpstat -P ALL 1 → 确认哪些核 iowait 高
→ iostat -x 1 → 确认哪块盘 await 高
→ iotop -o → 找读写进程
→ strace -e trace=read,write,fsync -p <PID> → 定位具体操作6.5 中断风暴定位
现象:%irq 或 %soft 整体异常高,vmstat 1 的 in 列骤增。
排查链:
mpstat -I SUM 1 → 看哪几个核中断总数暴涨
→ mpstat -I CPU 1 → 看具体哪种中断/哪个 IRQ 号在暴涨
→ cat /proc/interrupts | grep <IRQ号> → 确认设备
→ 设备问题或流量爆增,针对性处理七、交叉引用
- 整机CPU总览:top(先看整机再看逐核)
- 进程/线程级:pidstat(定位到哪个进程/线程在烧核)
- 软中断深入:interrupts §四(网卡收包完整流程)和 §五(softirq 机制)
- 中断亲和性:irq-affinity(分散中断到多核)
- 磁盘 IO:iostat(iowait 高时进一步定位)
- 上下文切换:vmstat(看 cs 和 in 的整体趋势)
- 数据源:procfs §三(/proc/stat 和 /proc/interrupts)
八、结合本仓库
./cpu_demo & # 选场景 1(单线程用户态死循环)
mpstat -P ALL 1
# 预期:只有一个核 %usr 接近 100%,其余核 %idle 接近 100%
# —— 直观证明"这是单线程问题,多核帮不上忙"对比:若把 cpu_demo 改成开多个 busy_user_cpu 线程,再看 -P ALL,多个核会同时上去。
七、和其他工具的分工
- top 按
1也能逐核展开,但mpstat -P ALL 1输出是文本、可记录、含%irq/%soft更全,适合抓中断问题。 - 定位到"哪个核忙"后,用
top -H/pidstat -t找是哪个线程跑在上面。
总结
mpstat 是逐核 CPU 与中断的体检工具:mpstat -P ALL 1 看每个核的 %usr/%sys/%idle,单核 100%、其余空闲说明是单线程瓶颈(多核帮不上忙),%iowait 高指向等 IO;它独有的价值是中断视角——%irq/%soft 异常配合 mpstat -I SUM/-I CPU 1 定位哪个核、哪种中断(IRQ 号)暴涨,再用 /proc/interrupts 确认设备。用法上它和 top 按 1 逐核展开信息接近,但文本可记录、中断列更全,定位到忙核后用 top -H/pidstat -t 找具体线程。