CPU使用率不高但服务响应慢,主因是上下文切换过频或软中断堆积,如NET_RX占满单核导致关键路径阻塞;需用vmstat、/proc/softirqs等工具定位,并检查RPS/RFS配置。

为什么 top 显示 CPU 使用率不高,但服务响应却很慢
这通常不是 CPU 瓶颈,而是 上下文切换过频 或 软中断(softirq)堆积 导致。比如网卡收包后触发大量 NET_RX 软中断,占满某个 CPU 核,而应用线程被调度到其他核上——看似整体负载低,实际关键路径被阻塞。
- 用
vmstat 1观察cs(context switch)列,持续 > 50000 表示异常频繁 - 用
cat /proc/softirqs查看NET_RX和NET_TX计数,对比各 CPU 核差异 - 检查是否启用了
RPS(Receive Packet Steering)或RFS(Receive Flow Steering),未启用时所有软中断默认集中在 CPU 0 上 - 临时缓解:通过
echo f > /proc/irq/*/smp_affinity_list(需按实际 IRQ 号替换)把网卡中断分散到多核
perf record -e cycles,instructions,cache-misses 跑出来没数据?
perf 默认只采集当前用户的进程事件,且内核需开启 perf_event_paranoid 权限。值为 2 时禁止非 root 采集内核态事件,-1 才允许全权限采样。
- 先执行
sudo sysctl -w kernel.perf_event_paranoid=-1 - 确认内核配置支持:
zcat /proc/config.gz | grep CONFIG_PERF_EVENTS应返回y - 若仍无
cache-misses数据,可能是 CPU 不支持该 PMU 事件(如某些 Atom 或旧 Xeon),改用perf stat -e cache-references,cache-misses更稳妥 - 注意
perf record默认采样频率为 4000Hz,高负载下可能丢样本,可加-F 100降低频率保完整性
调大 /proc/sys/kernel/sched_latency_ns 会让延迟更稳定吗
不会,反而可能加剧尾延迟(tail latency)。这个参数定义的是 CFS 调度器的“调度周期”,增大它意味着单个任务在一个周期内能分到更多时间片,但也会拉长其他任务的等待时间,尤其对小周期、高优先级的实时任务不利。
- 默认值通常是
6000000(6ms),在容器或微服务场景下建议保持默认,或仅微调至4000000(4ms)以提升响应灵敏度 - 真正影响稳定性的是
sched_min_granularity_ns:设得太小(如 2ms)则小任务得不到及时响应。推荐值:1000000(1ms) - 修改后必须配合观察
/proc/sched_debug中的nr_cpus和nr_switches变化,避免误伤吞吐
使用 cpupower frequency-set 切换 governor 后效果不明显
常见原因是用户空间 governor 未真正接管控制权,或者 BIOS 设置了 Intel SpeedStep 或 AMD Cool'n'Quiet 锁定最低频率。
- 先确认当前生效的 governor:
cpupower frequency-info --governor,而非只看--policy - 检查 BIOS 中是否禁用
OS Control Mode(Intel)或CPPC(AMD),这些选项开启前,Linux 无法写入 P-state 寄存器 -
performancegovernor 并不等于“一直跑满频”,它只是移除降频限制,实际频率仍受thermal throttling或power limit (PL1/PL2)约束;可用turbostat -i 1实时观察Avg_MHz和Pkg_% - 若用在数据库类低延迟场景,建议搭配
isolcpus=managed_irq,1,2,3启动参数隔离 CPU,并将关键进程绑到隔离核上
CPU 性能调优最易被忽略的一点:几乎所有参数都依赖 workload 特性。Web 服务看重短请求延迟,批处理关注吞吐,而实时音视频则要求确定性调度——没有通用最优解,只有针对 perf script 输出的 callgraph 和 perf report --sort comm,dso,symbol 定位的真实热点做针对性干预才有效。











