我使用 gprof2dot 生成了下面的图表,它可视化了我的程序的分析输出。
我对图表有一些疑问:
首先,为什么调用树的根不是 main(),而根 Bat_Read() 甚至没有出现在我的程序中,而是在 .h 文件中声明。
其次,GMatrix是一个没有显式析构函数的C++类,它调用图中的两个函数是不合理的。几乎一半的时间花费也是不合逻辑的。
第三,图底部的长函数是什么,它花费了 6.94% 的时间?
您可以在新选项卡中阅读图表并放大它,以便清楚地看到它。
我使用 gprof2dot 生成了下面的图表,它可视化了我的程序的分析输出。
我对图表有一些疑问:
首先,为什么调用树的根不是 main(),而根 Bat_Read() 甚至没有出现在我的程序中,而是在 .h 文件中声明。
其次,GMatrix是一个没有显式析构函数的C++类,它调用图中的两个函数是不合理的。几乎一半的时间花费也是不合逻辑的。
第三,图底部的长函数是什么,它花费了 6.94% 的时间?
您可以在新选项卡中阅读图表并放大它,以便清楚地看到它。
我只是放大了图像,以便阅读。
最下面的函数很宽,只是因为它的名字很长,但它只是一个_M_Erase
红黑树的方法。它被称为半百万次galois_w16_region_multiply
。它的大小引起了你的注意,但实际上它只出现在大约 7% 的样本上。
如果你把图中没有父母的每一个方块都加起来,把它们的百分比加起来,你就得到了 100%。所有这些都表明gprof
' 通过调用图向上传播时间的方法是不稳定的,所以它认为事情在顶部,而实际上它只是无法弄清楚调用者是谁。
你不能从中看出太多。您可以考虑替代gprof
.
添加:Gprof 将一些入口代码放入使用 -pg 标志编译的每个函数中。因此,当 A 调用 B 时,B 中的代码通过使用返回地址并在函数表中查找它来试图找出调用它的例程。它使用它来增加一个计数器,说明 A 调用 B 的次数。如果由于某种原因它无法找出正确的调用者,则会出现如图所示的错误。例如,它说例程
~vector
~GMatrix
galois_w32_region_multby_2
galois_get_log_table
Bat_Read
位于调用链的顶端(函数中没有调用者)。更重要的是,它认为那main
是由 调用的Bat_Read
。
这是 gprof 的典型特征。