如何用perf统计同一模板函数内联副本跨多个调用点的总CPU耗时
特定函数/类方法CPU耗时统计方案
原生perf快速统计
perf本身支持跨调用栈聚合函数采样数据,无需额外工具即可完成统计:
- 对目标进程执行采样(替换
<PID>为实际进程ID,<采样秒数>为你需要的采样时长):perf record -g -p <PID> -- sleep <采样秒数> - 跨所有调用栈聚合符号耗时,直接过滤目标函数/类:
输出结果中的# 通用函数统计,替换<函数名关键字>即可 perf report -n --stdio --no-children --sort symbol | grep "<函数名关键字>" # 统计std::unordered_map所有成员函数总耗时 perf report -n --stdio --no-children --sort symbol | grep -i "unordered_map"Overhead列就是该类所有函数的CPU耗时占比,乘以总采样时长即可得到合计CPU消耗。--no-children参数保证只统计函数自身执行的耗时,不会将子函数调用的耗时重复计算到上层。
更高精度/自定义统计
如果需要更灵活的过滤和统计逻辑,可以结合FlameGraph工具链实现:
- 首先解析perf采样数据生成折叠栈:
perf script | stackcollapse-perf.pl > perf.folded - 统计所有包含unordered_map调用的总采样占比:
TOTAL=$(awk '{sum += $2} END {print sum}' perf.folded) UMAP_SUM=$(grep -i "unordered_map" perf.folded | awk '{sum += $2} END {print sum}') echo "std::unordered_map总CPU占比: $(echo "scale=2; $UMAP_SUM*100/$TOTAL" | bc)%"
注意事项
- 目标二进制文件需要保留符号信息,不要strip,编译时建议加
-g参数保证C++符号可以被正常解析。 - 如果只需要统计std::unordered_map所有实例的合计耗时,上述方法已经可以满足需求,不需要额外的动态追踪工具。如果需要区分不同实例的耗时,再使用bpftrace、systemtap等工具做实例地址级别的统计。
内容的提问来源于stack exchange,提问作者Dologan
相关产品推荐
相关产品推荐

