【发布时间】:2019-12-12 15:07:18
【问题描述】:
我想用 linux perf 分析我的 c++ 程序。 为此,我使用了以下三个命令,但我不明白为什么会得到三个完全不同的报告。
perf record --call-graph dwarf ./myProg
perf report
perf record --call-graph fp ./myProg
perf report
perf record --call-graph lbr ./myProg
perf report
我也不明白为什么main 函数不是列表中最高的函数。
我的程序的逻辑如下,main函数调用getPogDocumentFromFile函数调用fromPoxml调用toPred调用applySubst调用subst。此外toPred、applySubst 和subst 是递归函数。我希望他们成为瓶颈。
更多 cmets:我的程序运行大约 25 分钟,它是高度递归的并且分配了很多 (~17Go) 内存。我也用-fno-omit-frame-pointer 编译并使用最近的英特尔CPU。
有什么想法吗?
编辑:
再次思考我的问题,我意识到我不明白儿童专栏的含义。
到目前为止,我假设 Self 列是我们在调用堆栈顶部查看的函数的样本百分比,而 Children 列是调用堆栈中任何位置的函数的样本百分比。显然情况并非如此,否则 main 函数的子列距离 100% 不远。也许调用堆栈被截断?还是我完全误解了分析器的工作原理?
【问题讨论】:
-
几乎不可能给出一个具体的答案,除非你能煮出一个minimal reproducible example。快速浏览一下,对于所有调用图技术跟踪的函数,不同的配置文件并没有本质上的不同——它们只是包含一组不同的覆盖函数。当调用图不完整时,
main可能太低了。原因很多。 -
您能详细说明一下吗?为什么调用图经常不完整?我觉得如果调用图不完整,这些报告或多或少没用。
-
@rsaill,如果您认为某些调用堆栈收集方法会给您截断输出,那么您应该尝试 "
--no-children" option ofperf report: "disable ... Accumulate callchain子项到父项,以便随后可以显示在输出中。输出将有一个新的“子项”列,并将根据数据进行排序。它需要记录调用链“。当性能报告用于不完整的调用堆栈时,有时我会得到不正确的结果。 self 列是 f 本身的样本,children - f + 从它调用的所有函数。