如果还没有为 synprog 收集性能数据,必须进行收集。相关说明参见为 synprog 示例收集数据。收集了性能数据之后,就必须打开实验 test.1.er。
示例的此部分说明性能分析器如何将度量分配给递归序列中的函数。在抽样收集器收集的数据中,记录了每个函数调用实例,但在分析中,会汇集所有给定函数实例的度量。synprog 程序包含递归调用序列的两个示例:
-
函数 recurse() 对直接递归进行了说明。它调用函数 real_recurse(),该函数然后调用自身,直到满足测试条件。此时,它将执行一些需要用户 CPU 时间的工作,控制流会连续调用 real_recurse(),直至返回到 recurse()。
-
函数 bounce() 对间接递归进行了说明。它调用函数 bounce_a(),该函数检查是否满足测试条件。如果不满足,它将调用函数 bounce_b()。而 bounce_b() 又调用 bounce_a()。此过程会持续到满足 bounce_a() 中的测试条件为止。然后,bounce_a() 执行一些需要用户 CPU 时间的工作,控制流连续调用 bounce_b() 和 bounce_a(),直至返回到 bounce()。
这两种情况下,独占度量只属于完成实际工作的函数(real_recurse() 和 bounce_a())。这些度量会作为相容度量传递到调用最终函数的每个函数中。
-
在 [函数] 标签中,找到函数 recurse() 并将其选中。
可以使用 [查找] 工具而无需滚动函数列表。
函数 recurse() 有相容用户 CPU 时间,但其互斥用户 CPU 时间为零,因为 recurse() 只是调用 real_recurse()。
注意: 因为分析实验的实质是统计,所以在 synprog 上运行的实验可能会在 recurse() 中记录一个或两个概要事件,recurse() 可能会显示较小的互斥 CPU 时间值。但互斥时间会因为这些事件而远远小于相容时间。
-
单击 [调用者-被调用者] 标签。
选定的函数 recurse() 显示在中央窗格中。由 recurse() 调用的函数 real_recurse() 显示在下部窗格中。此窗格称为 [被调用者] 窗格。
-
单击 real_recurse()。
此时 [调用者-被调用者] 标签便会显示 real_recurse() 的信息:
-
因为在 recurse() 调用 real_recurse() 之后,real_recurse() 会递归调用其本身,所以 recurse() 和 real_recurse() 都将作为 real_recurse() 的调用者显示在 [调用者] 窗格(上部窗格)中。
-
由于 real_recurse() 调用自身,因此还会出现在 [被调用者] 窗格中。
-
对于占用实际用户 CPU 时间的 real_recurse(),还会显示互斥度量和相容度量。互斥度量向上传递到 recurse() 用作相容度量。
-
被调用者的归属度量受调用的递归性质的影响。在非递归调用序列中,单个被调用者会将其所有相容度量归属于调用者。在这种情况下,real_recurse() 是叶函数,并且是它本身的调用者和被调用者。为避免重复计算归属度量,被调用者不会显示归属时间。real_recurse() 作为被调用者出现可提供关于调用序列(而不是归属时间)信息。
-
同样,调用者的归属度量也受调用的递归性质的影响。未将 real_recurse() 所用的任何相容时间归属到调用者 recurse()(real_recurse() 的最终调用者)。相反,该时间会归属到占用互斥时间的调用者实例 real_recurse()。要检查 recurse() 的归属度量,应选中该函数。
-
在 [函数] 标签中,找到并选择函数 bounce()。
函数 bounce() 显示相容用户 CPU 时间,但其互斥用户 CPU 时间为零。这是因为 bounce() 的全部工作只是调用 bounce_a()。
-
单击 [调用者-被调用者] 标签。
[调用者-被调用者] 标签显示 bounce() 只调用一个函数 bounce_a()。
-
单击 bounce_a()。
此时 [调用者-被调用者] 标签便会显示 bounce_a() 的信息:
-
bounce() 和 bounce_b() 均作为 bounce_a() 的调用者出现在 [调用者] 窗格中。
-
此外,bounce_b() 因为被 bounce_a() 调用而出现在 [被调用者] 窗格中。
-
对于占用实际用户 CPU 时间的 bounce_a(),还会显示互斥度量和相容度量。这些度量会向上传递到调用 bounce_a() 的函数,成为相容度量。
-
bounce_b() 中的所有相容时间皆归属于对 bounce_a() 的调用,但 bounce() 中的任何相容时间都不会归属于对 bounce_a() 的调用。bounce() 和 bounce_b() 的相容时间不是分离的,而实际只是相同的时间呈现了两次。为避免重复计算归属时间,只有占用时间的函数的直接调用者才会显示归属时间。这种情况与 recurse() 和 real_recurse() 的情况相同。
-
因为 bounce_a() 是叶函数和中间函数,所以为避免重复计算归属时间,作为被调用者的 bounce_b() 不会将任何时间归属到 bounce_a()。
-
单击 bounce_b()。
此时 [调用者-被调用者] 标签便会显示 bounce_b() 的信息。bounce_a() 出现在 [调用者] 窗格和 [被调用者] 窗格中。由于 bounce_b() 不是叶函数,并会累计它调用完成工作的 bounce_a() 实例的相容时间,因此将正确显示被调用者的归属时间。
找到要找的内容了吗?如未找到,请将您的意见通过电子邮件发送至 docfeedback@sun.com。
法律声明