最新的Intel处理器提供了一种硬件功能(也称为Precise Event-Based Sampling (PEBS)
),以在某些采样的CPU事件(例如e
)上访问有关CPU状态的精确信息。这是Intel 64 and IA-32 Achitecture's Software Developer's Manual: Volume 3的摘录:
基于相同引用的Chapter 17
,用于x86-64
体系结构的DS格式如下:
BTS Buffer
记录最后执行的N
分支(N
取决于微体系结构),而PEBS Buffer
记录以下寄存器:
IIUC,设置了一个计数器,每个事件(e
)的出现都会增加其值。当计数器溢出时,会将条目添加到这两个缓冲区中。最后,当这些缓冲区达到一定大小(BTS Absolute Maximum
和PEBS Absolute Maximum
)时,将生成一个中断,并将这两个缓冲区的内容转储到磁盘。这将定期发生。似乎--call-graph dwarf
backtrace数据也在同一处理程序中提取,对吗?
1)这是否意味着LBR
和PEBS
(--call-graph --lbr
)状态完美地匹配在一起?
2)不属于--call-graph dwarf
的PEBS
输出如何(在上面的引用资料中显而易见)? (某些RIP/RSP
与回溯不匹配)
确切地说,这是LKML Thread,其中Milian Wolff
显示第二个问题为NO。但是我不完全理解原因吗?
第一个问题的答案也为“否”(由该线程后面的消息中的Andi Kleen
表示),我根本不理解。
3)这是否意味着整个DWARF
调用图信息已完全损坏?
上面的线程没有显示这一点,在我的实验中,我没有看到任何与回溯不匹配的RIP
。换句话说,我可以相信回溯的多数吗?
我不喜欢LBR
方法,它本身可能并不精确。回溯的大小也受到限制。虽然,here是克服大小问题的补丁。但这是最近的事情,可能是虚假的。
更新:
Perf
在PEBS Buffer
中仅存储单个记录?例如,当PEBS
事件需要调用图信息时,是否只能间接强制这种配置? 最佳答案
1)您引用的手册部分谈论的是BTS,而不是LBR:它们不是一回事。您引用了Later in that same thread,Andi Kleen似乎表示LBR捕捉时间实际上是PMI(运行处理程序的中断)的时刻,而不是PEBS时刻。因此,我认为所有三种堆栈方法都存在相同的问题。
2)DWARF堆栈捕获肯定与PEBS条目不完全对应。 PEBS事件由硬件在运行时记录,然后仅在一段时间之后CPU中断,此时堆栈被取消缠绕。如果将PEBS缓冲区配置为仅容纳单个条目,则至少应该关闭这两件事,并且如果幸运的话,当处理程序运行时,PEBS IP将处于与堆栈顶部相同的功能。在那种情况下,堆栈基本上是正确的。由于perf
在顶部显示了实际的PEBS IP,以及在捕获的图像下方显示的帧,因此在这种情况下可以正常工作。
3)如果您不走运,该功能将在PEBS捕获和处理程序运行之间进行更改。在这种情况下,您会得到毫无用处的弗兰肯堆栈:顶部函数可能无法从顶部第二个函数(或某些函数)调用。它并没有完全损坏:只是顶部框架以外的所有内容都来自捕获PEBS堆栈后的某个点,顶部框架来自PEBS或类似的东西。出于相同的原因,这也适用于--call-graph fp
。
很可能您从未见过无效的IP,因为perf
显示了PEBS示例中的IP(这是整个线程的主题)。我认为,如果您查看原始样本,那么既可以看到PEBS IP,也可以看到处理程序IP,并且可以看到它们通常不匹配。
总体而言,您可以信任“时间”或“周期”配置文件的回溯,因为从某种意义上说,它们是执行时间的准确采样表示:只是它们与PEBS时刻不对应,而是在一段时间之后(但为什么是)后来的时间比PEBS的时间还差)。基本上,对于这种类型的分析,您实际上根本不需要PEBS。
如果您使用的是其他类型的事件,并且希望对事件发生的位置进行细粒度的核算,那么PEBS就是这么做的。您通常不需要堆栈跟踪:仅顶部框架就足够了。如果要使用堆栈跟踪,请使用它们,但要知道它们稍后会出现,或者使用--lbr (if that works)
。