使用 perf 进行性能监控

Performance monitoring with perf

免责声明:我是 perf 的新手,仍在努力学习 ins/outs。

我有一个可执行文件 运行ning 在我的目标系统 运行ning Linux 上。我想使用 perf 来 profile/monitor 随着时间的推移它的性能。为了论证,我试图证明我的 CPU 当前从 top 和 collectD 测量的利用率可以通过 perf 监视它来替换,这将导致更精细的数据。

因为我们试图随着时间的推移获得一个情节,所以我一直在使用 perf record -e cycles -p <pid>。之后我可以通过 perf report 获取要显示的数据。

问题:

  1. 仅显示带有 perf report 的数据显示了我的摘要 我获取的整个数据集是否正确?
  2. 如果我要 运行 perf report -D 我会得到所有数据的转储。 (附带一个问题,时间戳是 ns 中的正常运行时间吗?)现在我假设样本是基于可以在 perf record 中设置的频率,对吗?我 运行 通过获取时间戳的时间增量来解决问题,它似乎是以随机间隔记录的。
  3. 一旦我转储了数据,这里就没有什么可以真正大喊大叫了 "this is your count!!" 所以我假设转储中的 "period" 字段是原始计数。这是真的?这意味着如果 period = 100,我可以假设在那个时间间隔内,我的程序使用了 100 个周期?此外,我开始觉得这不仅适用于应用程序,还适用于程序进行的每个库或内核调用。 IE。如果一个 malloc 被调用,一个不同的事件将被记录,概述调用周期。所以总的来说,我如何才能得出持续时间或事件 + 事件的周期数 + 它实际上来自该字段的哪个事件才能真正衡量 CPU 利用率?

如果 perf 的这个应用程序不是它想要做的那么我也想知道为什么不呢?此外,我认为这种相同类型的分析对于所有其他类型的统计数据也很有用,因为您可以及时查明 运行ning 代码中发生异常的时间。仅供参考,我 运行ning perf 反对 1s 的顶级收集。我这样做是因为我想将最高输出与 perf 输出进行比较。任何见解都会有所帮助,因为正如我所说,我仍在学习这个强大的工具并且是新手。

(Linux 内核版本: 3.10.82)

答案 #1

大部分是。 perf report 确实向您显示了所收集跟踪的摘要。 perf record 收集的样本保存在一个二进制文件中,默认情况下名为 perf.dataperf report 命令读取此文件并生成简明的执行配置文件。默认情况下,样本按函数排序,样本最多的排在最前面。但是,您也可以使用此报告进行更详细的分析。

答案 #2

最好使用 perf script -D 来跟踪所有数据。时间戳以 微秒 为单位。虽然,内核比您指定的内核更新,但在命令行开关 (-ns) 的帮助下,您可以 纳秒 显示时间以及。这是来源-

Timestamp

如果不看您得到的是哪种 "deltas",很难说清楚这一点。请记住,通常会调整收集样本的周期。有两种指定采样率的方法 --

您可以使用perf record (--c for count)指定采集样本的时间段。这将意味着对于您正在测量的事件的每 c 次出现,您都会有一个样本。然后您可以修改采样周期并测试各种值。这意味着您正在测量的事件每发生两次,计数器就会溢出,您将记录一个样本。

表示采样周期的另一种方法是指定每秒采样的平均速率(频率)- 您可以使用 perf record -F 来实现。因此 perf record -F 1000 将每秒记录大约 1000 个样本,这些样本将在事件对应的 hardware/PMU 计数器溢出时生成。这意味着内核将动态调整采样周期。您将在不同的随机时刻获得采样时间。

您可以在此处的代码中亲自查看:

How perf dynamically updates time

答案 #3

为什么不呢?理想情况下,如果您执行 perf report 并进行更深入的分析,您应该获得收集的事件样本数。此外,当您执行 perf record 并完成样本记录时,您会在命令行上收到有关与您测量的事件相对应的样本收集数量的通知。 (这可能在您使用的内核模块中不可用,我建议您尽可能切换到更新的 linux 版本!)。 样本数 应该是原始计数 - 而不是周期。

如果您的周期是 100 - 这意味着在跟踪的整个持续时间内,perf 每 100 个事件记录一次。这意味着,如果在跟踪持续时间内总共发生了 1000 个事件,perf 大约收集到事件 1、100、200、300...1000。

是的,记录的示例不仅来自应用程序。事实上,您可以使用这样的开关:perf record -e <event-name:u> or <event-name:k>(u 代表用户空间,k 代表内核)来记录事件。此外 perf 还记录来自共享库的样本。 (有关详细信息,请参阅 perf 手册页 )。

正如我之前所说,perf report 应该是计算 perf 记录的事件 cycles 的样本数的理想工具。事件数 collected/recorded 并不准确,因为硬件不可能记录所有 cycle 事件。这是因为记录和准备所有事件的详细信息需要内核维护一个 环形缓冲区 ,当计数器溢出时,它会定期写入。这种对缓冲区的写入是通过中断发生的。它们占用了 CPU 时间的一小部分——这段时间丢失了,本来可以用来记录现在由于 CPU 忙于服务中断而丢失的事件。尽管如此,您仍然可以通过 perf 获得非常好的估算值。

结论

perf 在我们目前手头的硬件资源有限的情况下,特别做了它打算做的事情。我建议浏览每个命令的手册页以更好地理解。

问题

  1. 我假设您正在查看 perf report。我还假设您在谈论 perf report 中的 开销 %。从理论上讲,它可以被认为是按照您指定的从最高到最低的顺序排列数据。但是,您需要考虑和理解许多基础细节才能正确理解输出。它表示哪个函数的开销最大(根据该函数中发生的事件数)。在所有函数及其开销之间,还存在父子关系,基于哪个函数调用哪个函数。请使用Perf Reportlink了解更多。

  2. 如您所知,事件正在被抽样,而不是被计算在内。所以你不能准确地得到事件的数量,但是你会得到样本的数量,并且根据收集样本的调谐频率,你还会得到事件数量的原始计数(一切都应该可用 perf report 输出).