perf stat是Linux内核自带的性能分析工具,通过硬件性能计数器(PMC)采集CPU流水线效率、内存子系统性能及系统调用开销等指标,能精准定位如IPC下降、缓存未命中、分支预测失败等底层瓶颈。

Linux 没有“指令流水线停顿”这种用户态可直接查看的硬件级性能事件记录——这不是 shell 命令或日志文件能直接输出的东西。你要查的是 CPU 微架构层面的流水线气泡(pipeline stall)、分支预测失败、缓存未命中等底层行为,必须依赖性能监控工具(PMU)和内核支持。
docker logs -f 看不到流水线停顿,它只输出应用 stdout/stderr
很多人混淆了“流水线”概念:docker logs -f 中的 “pipeline” 是指 CI/CD 流水线(如 Jenkins/GitLab CI),不是 CPU 指令流水线。前者日志在容器里,后者是 CPU 内部状态,二者完全无关。
-
docker logs输出的是进程打印到终端的文字,和 CPU 执行效率毫无关系 - 即使容器里跑的是一个 tight loop,
docker logs -f也永远不会显示 “ICACHE_MISS” 或 “REPLAY_STALL” 这类信号 - 试图用
grep "stall"过滤容器日志,结果一定是空的——除非你的应用自己打印了这个词
真要查 CPU 指令流水线停顿,得用 perf + hardware events
perf 是 Linux 唯一广泛可用、能访问 CPU PMU 的用户态工具。它能采集硬件性能计数器,其中就包括与流水线停顿强相关的事件:
-
perf stat -e cycles,instructions,uops_issued.any,uops_retired.retire_slots,resource_stalls.any—— 查看整体吞吐与资源瓶颈 -
perf record -e cycles,instructions,idq_uops_not_delivered.core,lsd_cycles_empty—— 针对 Intel CPU 的解码/发射/调度阶段停顿 -
perf report -F overhead,symbol—— 定位具体函数或指令在哪种 stall 上耗时最多
注意:resource_stalls.any 在较新内核(5.10+)和 Intel CPU 上才稳定支持;ARM 平台需用 arm_spe 或 cpu/event=0x11/ 类似编码,且需开启 CONFIG_ARM_SPE_PMU 内核选项。
常见误判:把 scheduler delay 当成 pipeline stall
有人看到 perf sched latency 或 /proc/<pid>/schedstat</pid> 里有 “delay” 字样,就以为是 CPU 流水线卡住了。其实那是调度延迟(进程就绪但没拿到 CPU),属于 OS 层面问题:
-
sleep_avg、wait_sum、nr_voluntary_switches都在/proc/<pid>/sched</pid>里,反映的是进程等待时间,不是指令执行停滞 - 真正影响指令级并行的是
uops_retired.stall_cycles(Intel)或l1d_cache_refill(ARM),不是se.exec_start - 如果
perf stat显示instructions/cycle 且 <code>resource_stalls.any > 20%,才值得怀疑流水线瓶颈;否则大概率是代码逻辑或内存带宽限制
最后提醒一句:没有 root 权限或未启用 perf_event_paranoid(通常需设为 -1 或 0),perf 无法读取大多数硬件事件——这时候你看到的全是 0,不是没 stall,是根本没权限采样。


















