我想用linux来分析我的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,后者调用调用subst的applySubst。此外,toPred、applySubst和subst都是递归函数。我希望他们成为瓶颈。
还有一些评论:我的程序运行大约25分钟,它是高度递归的,并分配了大量的内存(~17 my )。此外,我使用-fno-omit-frame-pointer进行编译,并使用最近的英特尔CPU。
知道吗?
编辑:
再一次思考我的问题,我意识到我不理解“儿童”专栏的意义。
到目前为止,我假设Self列是在调用堆栈顶部显示函数的样本的百分比,而子列是在调用堆栈中任何地方都有函数的样本的百分比。显然不是这样,否则主要功能的子列就不会超过100%。也许调用堆栈被截断了?还是我完全误解了分析器的工作方式?
发布于 2020-01-03 04:21:36
Man page of pref report将显示的调用链与子积累记录在一起:
-子级积累到父条目的调用链,这样就可以在输出中显示出来。输出将有一个新的“子”列,并将对数据进行排序。它要求呼叫链被记录下来。有关详细信息,请参阅“开销计算”部分。默认情况下启用,禁用无子级。
我可以建议您使用--no-children选项perf report (或perf top -g --no-children -p $PID_OF_PROGRAM)尝试非默认模式。
因此,在默认模式下,当perf.data文件中有一些调用链数据时,perf报表将计算"self“和"self+children”开销,并对累积的数据进行排序。这意味着,如果某个函数f1()有10%的“自我”样本,并以20%的“自我”样本调用某些叶函数f2(),则f1() self+children将为30%。累积的数据是所有提到当前函数的堆栈的数据:用于在其中完成的工作,以及在所有直接和间接子代(后代)中的工作。
您可以在--call-graph选项(侏儒/ lbr / fp)中指定一些调用堆栈抽样方法,它们可能有一些限制。有时方法(特别是fp)可能无法提取调用堆栈的部分。-fno-omit-frame-pointer选项可能会有所帮助,但是当它在您的可执行文件中使用而不是在某些回调库中使用时,则会部分提取调用堆栈。一些很长的调用链可能也不会被某些方法提取。或者perf report可能无法处理某些案件。
若要检查截断的调用链示例,请在中间某个位置使用perf script|less。在这种模式下,它会打印所有检测到的函数名的记录样本,检查没有以main和__libc_start_main结尾的示例--它们被截断。
,否则主函数的子列将不超过100%。
是的,对于单线程程序和正确记录和处理的调用堆栈,main应该有大约99%的“子”列。对于多线程程序,第二个线程和其他线程将有另一个根节点,如start_thread。
https://stackoverflow.com/questions/59307540
复制相似问题