gprof是如何工作的?

17

这是一个有点庞大的问题,所以我会提前道歉。我对gprof在技术层面上的工作方式感到好奇。我知道它是通过计时器完成的,但是为什么需要特别编译可执行文件才能进行性能分析呢?编译是否会导致为统计数据分配空间?

此外,定时是如何精确完成的?

2个回答

10

刚刚再次阅读了论文,让我试着解释一下。

假设它以100Hz的速度采样,除非进程因IO或其他原因被阻塞。每个样本记录PC,该PC位于某个函数中。该函数中的样本计数递增。

因此,在运行结束时,如果有(比如)1000个样本,那么总执行时间(仅CPU)为10秒。如果例程B记录了500个这些样本,则其总执行时间为总时间的1/2,即5秒。这是它的自身时间,因为PC在其中。这并不告诉平均执行时间多长。要知道这一点,需要知道它被调用的次数。还不包括在被调用者中花费的时间。

当使用-pg标志编译代码时,在每个例程的入口代码中插入了一个特殊的调用。它注意到进入例程B,并注意到它是从例程A的调用点调用的。有一个表,由该调用点索引,可以计算出该调用。因此,在最后,gprof可以告诉我们B被调用了多少次,其中有多少次来自A。

要获得B的平均自身时间,需要将其总自身时间除以它被调用的次数。

为了获得例程A的总累计时间(自身加上被调用的时间),gprof需要A的自身时间,加上它调用每个下属例程B的总次数,乘以B的平均累计时间。然后将该数字除以对A的总调用次数,以获取A的平均累计时间。
听起来很不错,直到递归进入图像,使其变得更加混乱。
这一切都非常聪明,正如作者所指出的那样,充满了注意事项。

嗨,这个选项和-finstrument-functions选项有什么区别? - Elinx
@elinx: -finstrument-functionsgcc选项(不是gprof),它允许您将编写的入口和退出函数放入编译器处理的每个例程中。它只会给出调用方和被调用方的地址,因此您需要进行一些后处理。如果您想进行计时,您需要找出如何进行计时。这离诊断性能问题还有很长的路要走。我在 这个短视频 中展示了一个简单的方法来实现。 - Mike Dunlavey

9

好的,这里有一个好的解释。同时,这也解释了统计分析

基本上,gprof会改变您的程序可执行文件(这称为代码插装),以存储一些簿记信息,例如函数被调用的次数。

统计分析部分来自于定期窥探程序计数器,以获得代码正在执行的样本。

Gprof两者都做。它对代码进行插装,并从查看程序计数器中收集样本。


1
它不也需要爬上堆栈才能获得可靠的跟踪吗? - alexgolec
2
@Alex:它没有实现这一点是它的主要问题之一。 - Mike Dunlavey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接