3

最近的 Intel 处理器提供了一个硬件功能(又名Precise Event-Based Sampling (PEBS))来访问有关某些 CPU 采样事件(例如 )的 CPU 状态的精确信息e。这是英特尔 64 和 IA-32 架构的软件开发人员手册:第 3 卷的摘录

18.15.7 处理器基于事件的采样(PEBS)

基于英特尔 NetBurst 微架构的处理器中的调试存储 (DS) 机制允许收集两种类型的信息以用于调试和调整程序:PEBS 记录和 BTS 记录。

基于Chapter 17相同的参考,x86-64架构的DS格式如下: 在此处输入图像描述 记录BTS Buffer最后N执行的分支(N取决于微架构),同时PEBS Buffer记录以下寄存器: 在此处输入图像描述 IIUC,设置一个计数器,每个事件(e)发生递增它的价值。当计数器溢出时,将向这两个缓冲区添加一个条目。最后,当这些缓冲区达到一定大小(BTS Absolute MaximumPEBS Absolute Maximum)时,会产生中断,并将两个缓冲区的内容转储到磁盘。这会定期发生。似乎--call-graph dwarf回溯数据也是在同一个处理程序中提取的,对吧?

1) 这是否意味着LBRPEBS( --call-graph --lbr) 状态完美匹配?

--call-graph dwarf2)不属于的输出怎么样PEBS(在上面的参考中似乎很明显)?(有些RIP/RSP不匹配回溯)

准确地说,这是一个LKML Thread,其中Milian Wolff显示第二个问题NO。但我不完全明白原因?

第一个问题的答案也是,NOAndi Kleen在线程的后面消息中表示),我完全不明白。

3)这是否意味着整个DWARF调用图信息已完全损坏?

上面的线程没有显示这一点,在我的实验中我没有看到任何RIP不匹配的回溯。换句话说,我可以相信大多数回溯吗?

我不喜欢这种LBR方法本身可能不精确。它还受限于回溯的大小。虽然,是一个克服尺寸问题的补丁。但这是最近的,可能是假的。


更新:

  • 怎么可能强制Perf只存储一条记录PEBS Buffer?是否只能间接强制此配置,例如,当PEBS事件需要调用图信息时?
4

1 回答 1

2

1)您引用的手册部分谈论的是BTS,而不是LBR:它们不是一回事。稍后在您引用的同一线程中,Andi Kleen 似乎表明 LBR 快照时间实际上是 PMI(运行处理程序的中断)的时刻,而不是 PEBS 时刻。所以我认为所有三种堆栈方法都有相同的问题。

2) DWARF 堆栈捕获肯定与 PEBS 条目不完全对应。PEBS 事件在运行时由硬件记录,然后仅在一段时间后 CPU 中断,此时堆栈被展开。如果 PEBS 缓冲区被配置为只保存一个条目,那么这两个东西至少应该是接近的,如果幸运的话,当处理程序运行时,PEBS IP 将位于仍然位于堆栈顶部的同一个函数中。在那种情况下,堆栈基本上是正确的。由于perf在顶部向您显示了实际的 PEBS IP,加上捕获的帧下方的帧,这最终在这种情况下工作。

3) 如果你不走运,函数将在 PEBS 捕获和处理程序运行之间发生变化。在这种情况下,您会得到一个没有意义的 franken-stack:top 函数可能无法从第二个函数(或其他函数)调用。它并没有完全损坏:只是除了顶部帧之外的所有内容都来自捕获 PEBS 堆栈之后的某个点,而顶部帧来自 PEBS 或类似的东西。--call-graph fp出于同样的原因,这也适用于。

很可能您从未见过无效 IP,因为perf它显示了 PEBS 示例中的 IP(这是整个线程的主题)。我认为,如果您查看原始样本,您可以同时看到 PEBS IP 和处理程序 IP,并且您可以看到它们通常不匹配。

总体而言,您可以相信“时间”或“周期”分析的回溯,因为它们在某种意义上是执行时间的准确采样表示:只是它们不对应于 PEBS 时刻,而是一段时间后(但为什么以后的时间比 PEBS 时间差)。基本上,对于这种类型的分析,您根本不需要 PEBS。

如果您使用的是不同类型的事件,并且您希望对事件发生的位置进行细粒度的记账,那么这就是 PEBS 的用途。您通常不需要堆栈跟踪:只需顶部框架就足够了。如果您想要堆栈跟踪,请使用它们,但要知道它们来自稍后的某个时刻,或者使用--lbr (if that works).

于 2020-04-19T03:44:37.563 回答