度量归属和 gprof 谬误

如果还没有为 synprog 收集性能数据,必须进行收集,并打开实验 test.1.er。相关说明参见为 synprog 示例收集数据

在此示例中,可以使用 [调用者-被调用者] 标签来研究如何将函数占用的时间归为其调用者。

  1. 在 [函数] 标签中,选择 gpf_work(),然后单击 [调用者-被调用者] 标签。

    [调用者-被调用者] 标签分为三个窗格。中央窗格中是选定的函数。上部窗格中是选定函数的调用者,下部窗格中是选定函数调用的函数,称为被调用者。

    [调用者] 窗格显示调用选定函数的两个函数:gpf_b()gpf_a()。由于 gpf_work() 没有调用任何其它函数,因此 [被调用者] 窗格为空。此类函数称为“叶函数”。

    检查 [调用者] 窗格中的归属用户 CPU 时间列。调用者的归属时间是指从该调用者处调用选定函数所用的时间。gpf_work() 所用时间多数是由于从 gpf_b() 进行调用所致。而极少时间是由从 gpf_a() 进行调用所致。

    gpf_work() 所用时间中,从 gpf_b() 调用所用的时间几乎是从 gpf_a() 调用所用的时间的十倍,要了解其中的原因,必须检查两个调用者的源代码。

  2. 单击 [调用者] 窗格中的 gpf_a()

    gpf_a() 成为选定函数,并移至中央窗格;该函数的调用者出现在 [调用者] 窗格中,该函数的被调用者 gpf_work() 出现在 [被调用者] 窗格中。

  3. 单击 [源] 标签并向下滚动,以便查看 gpf_a()gpf_b() 的代码。

    gpf_a() 以 1 为参数,调用 gpf_work() 十次,而 gpf_b() 以 10 为参数,只调用 gpf_work() 一次。参数从 gpf_a()gpf_b() 传递到 gpf_work() 中的形式参数 amt

    现在检查 gpf_work() 的代码,以了解调用者用不同方法调用 gpf_work() 会有所不同的原因。

  4. 向下滚动以显示 gpf_work() 的代码。

    检查计算变量 imax 的代码行:imax 是随后的 for 循环的上限。执行 gpf_work() 所占用的时间取决于参数 amt 的平方。因此,以 10 为参数从函数进行一次调用所用的时间(400 次迭代)是以 1 为参数从函数进行十次调用所用时间(4 次迭代的 10 个实例)的十倍。

    但在 gprof 中,函数占用的时间是根据调用的次数进行估算的,而不考虑函数的参数或函数可以使用的任何其它数据如何决定时间。因此对于 synprog 的分析,gprof 错误推导出从 gpf_a() 调用所需的时间是从 gpf_b() 调用所需时间的十倍。此即 gprof 谬误。

另请参见
调用者-被调用者标签
源标签
互斥、相容和归属度量

找到要找的内容了吗?如未找到,请将您的意见通过电子邮件发送至 docfeedback@sun.com。
法律声明