最直接有效的方式是 perf record -g ./your_program,它能采样调用栈定位真正吃 CPU 的函数,需加 -g 生成调用图,配合 -g -O2 编译、-F 99 提高采样频率,并用 perf report -n --no-children 分析。

直接用 perf record 采样 + perf report 查看函数级占比,就能快速定位 CPU 瓶颈所在。关键不是“能不能看到”,而是采样是否准确、调用栈是否完整、符号是否可读。
准备环境:确保能解析函数名
perf 默认只记录内存地址,看不到函数名——必须安装调试符号包:
- Debian/Ubuntu 系统:装
ceph-osd-dbg(OSD)、ceph-mon-dbg(MON)等对应-dbg包 - RHEL/CentOS/Fedora:装
ceph-osd-debuginfo类似命名的-debuginfo包 - 确认内核参数允许 perf 采集:
echo -1 | sudo tee /proc/sys/kernel/perf_event_paranoid
实时观察热点:perf top 最快上手
适合快速判断“现在谁在吃 CPU”:
-
sudo perf top -p $(pgrep -n ceph-osd):只盯一个 OSD 进程 - 加
-g参数(perf top -g)可展开调用栈,看清是哪个上层逻辑触发了底层函数 - 按
o可按开销排序,P可聚焦某个函数查看其调用者和被调用者
精准归因:record + report 定位消耗占比
比 top 更可靠,支持事后回溯和细粒度分析:
- 采样 60 秒并记录调用图:
sudo perf record -F 99 -p $(pgrep -n ceph-osd) -g -- sleep 60 - 生成带符号的报告:
sudo perf report -g --no-children,重点关注 “Overhead” 列 - 若想看某函数的调用来源,将光标移至该函数按
Enter,即可展开上游调用链 - 加
--call-graph dwarf(需编译时带-gdwarf-4)可提升深度调用栈还原准确率
可视化辅助:火焰图一眼锁定“元凶”
当调用层级深、函数多时,文字报告易遗漏上下文:
- 生成采样数据:
sudo perf record -F 99 -p $(pgrep -n ceph-osd) -g -- sleep 60 - 转成火焰图:
sudo perf script | stackcollapse-perf.pl | flamegraph.pl > cpu-flame.svg - 打开 SVG 文件,宽度越宽的函数块,CPU 占比越高;纵向堆叠体现调用关系;顶部函数是叶子节点,底部是入口
- 特别注意“扁平但高”的窄条——可能是高频小函数(如锁、原子操作),也可能是热点路径上的关键瓶颈


















