人人都会AI编程

20.2 CPU 性能分析

更新时间:2026-07-12

CPU 性能问题通常表现为系统响应变慢、应用延迟升高或服务器负载飙升。分析 CPU 性能,核心任务是回答三个问题:哪些进程在消耗 CPU?它们在执行什么代码?是否存在不合理的使用模式? 下面从常用工具、分析流程和典型场景展开,力求实用、可复现。


1. 快速总览:确定 CPU 的总体状态

先用全局工具快速判断 CPU 是否饱和、竞争在哪里。

  • uptime:查看过去 1、5、15 分钟的平均负载。若平均负载持续高于 CPU 逻辑核数,说明有进程在排队等待 CPU。
  uptime
  # 12:34:56 up 10 days, 2:15, 3 users, load average: 4.52, 3.89, 3.12
  
  • tophtop:动态查看总 CPU 利用率(us 用户态、sy 内核态、id 空闲、wa 等待 I/O、hi/si 硬/软中断)。重点关注 ussy 的占比:业务进程消耗用户态 CPU,驱动或系统调用频繁会导致 sy 升高。
  top
  # 按 1 展开各 CPU 核心,按 P 按 CPU 用量排序,按 q 退出。
  
  • vmstat 1:每秒输出一次系统整体运行队列(r 列)、上下文切换(cs)、中断(in)和 CPU 时间分布。r 值持续高于 CPU 核数表示 CPU 成为瓶颈。
  vmstat 1
  # r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
  # 3  0      0 162340  43212 1453421    0    0    15     8  152  310 45 12 40  3  0
  

wa(I/O 等待)很高时,CPU 可能并非计算瓶颈,而是等待磁盘或网络,应转而检查存储或 I/O 子系统。


2. 定位高消耗进程和线程

  • top/htop 的进程列表直接显示 CPU 占用率(%CPU),可以按 P 键排序。
  • pidstat 1(来自 sysstat 包):按进程查看每秒 CPU 使用率,并区分用户态(%usr)、内核态(%system)、客户机(%guest)等。对后台守护进程特别有用。
  pidstat 1
  # 每 1 秒打印一次进程 CPU 统计。
  
  • 若需要看线程级别(如 Java 多线程),使用 pidstat -t -p <PID> 1top -H -p <PID>

3. 挖出 CPU 消耗的具体函数:使用 perf

知道哪个进程高消耗后,需要知道它到底在忙什么——是在做浮点运算、字符串处理,还是频繁系统调用?

perf 是 Linux 内核内置的性能分析器,采样开销低,适合生产环境。

  • 实时采样进程perf top -p <PID>

动态展示占用 CPU 最多的函数,结果类似 top,但聚焦到代码级。

  • 记录并报告(最常用)
  perf record -p <PID> -g -- sleep 30   # 采样 30 秒,-g 记录调用栈
  perf report                             # 交互式查看报告
  

报告中会列出函数及其 CPU 占比。若开启 -g,可展开函数调用的父子关系,直观看到热点路径。

结合火焰图工具(如 Brendan Gregg 的 FlameGraph 脚本),可将 perf record 的数据转换为一目了然的 SVG 图形,快速定位顶层热点。


4. 区分用户态与内核态消耗

  • 如果 %system 高,说明进程大量执行系统调用或触发内核活动。用 strace -c -p <PID> 统计系统调用次数和耗时,寻找不合理的调用(如短时间读写几百字节而不是批量操作)。
  • 使用 perf 也可以区分:采样时默认混合用户和内核态,报告时选择分列查看;或使用 perf record -e cycles:u -p <PID> 仅采样用户态,比较与全态的差异。

注意:strace 高负载时可能拖慢进程,谨慎在生产环境中长时间使用,可先用 perf 定位问题再针对性补充。


5. 多核利用与负载分布

  • mpstat -P ALL 1:查看各 CPU 核心利用率,揪出“单核心瓶颈”(某个核心 100% 而其他空闲)。常见于单线程程序或中断绑定不当。
  mpstat -P ALL 1
  
  • 如果有单个进程占满一个核心,其他核心却很闲,需要检查应用是否能并行化、线程数设置是否合理。

6. 实时性和延迟分析

当 CPU 并非始终满载,但偶尔出现尖峰导致业务抖动时:

  • 使用 perf sched recordperf sched latency 分析调度延迟,查明进程是否长时间得不到 CPU。
  • 对于软实时需求(如音频、高频交易),可配合 chrt 调整进程调度策略(SCHED_FIFOSCHED_RR)并分配优先级。

7. 典型诊断流程

假设用户反馈应用响应慢,按以下步骤排查:

  1. uptime → 平均负载 > CPU 核数,负载高。
  2. top → 看到 us 高,wa 低,CPU 本身在忙碌。
  3. toppidstat → 确定进程 myapp(PID 3456)占用约 80% CPU。
  4. perf top -p 3456 → 发现大量 CPU 消耗在 regex_compile 函数,推测正则表达式编译被频繁调用。
  5. 验证:检查代码,发现请求内部每次都构造 regex,移至初始化阶段编译一次复用,CPU 占用骤降。

8. 工具速查表

| 场景 | 工具 | 要点说明 |
|------------------------------|------------------------------|------------------------------------------|
| 全局负载判断 | uptime, vmstat, top | 关注 r、平均负载和 idle |
| 进程/线程 CPU 占用 | top -H, pidstat -t | 结合 -p 指定 PID |
| 函数级热点分析 | perf top, perf record/report | 使用 -g 抓取调用栈,配合火焰图更直观 |
| 系统调用统计 | strace -c, perf stat | perf stat 可得到指令、缓存等硬件计数 |
| 各核心均衡度 | mpstat -P ALL | 发现单核心瓶颈 |
| 调度与中断异常 | perf sched, /proc/interrupts | 检查中断分布和调度延迟 |
| 快速实时监控(脚本友好) | sar -u 1(来自 sysstat) | 后台记录 CPU 历史数据 |

掌握这些基础手段,已经足以诊断大部分生产环境中的 CPU 性能问题。关键是形成“从全局到局部、从进程到函数”的分析习惯,并用数据验证优化效果。