我正在寻找答案,但没有找到明确的答案。我该如何解释perf report
输出中的第一行。它是这样的:
Samples: 173M of event 'cache-misses', Event count (approx.): 461731712088
我看过的几乎每个教程都讲到了所有内容,除了第一行。本页解释了样本和计数之间的区别,但我想 100% 确保我没有得出错误的结论:在我的例子中,173M
和461731712088
是什么意思?从我读到的内容来看,我猜第二个是运行时发生的缓存未命中总数,第一个是记录并用于显示统计信息的缓存未命中数。这是正确的还是我误解了输出?
你说得对。对于硬件事件(而不是页面错误和上下文切换等软件事件),
perf record
通过在 PMU 中编程 HW 计数器来记录硬件事件每次发生时的样本。(“记录样本”是指写入 PEBS 缓冲区1或只是当场发出中断。)n
n
选择某种采样频率,不会导致太多中断,从而严重扭曲性能,但也会在运行您正在分析的任何内容的几秒钟到几分钟内为该事件收集合理数量的样本。这可能意味着n
动态调整,或为不同事件设置默认值。(例如,instructions
通常每时钟发生超过 1 次,而非常罕见的事件则为machine_clears.count
。)实际的 PMU 硬件使用 进行编程
n
,并向 0 倒计时(或者可能向 0 倒计时n
并进行比较)。perf stat
通过设置一个巨大的n
(与硬件支持的最大值一样大)来工作,因此它只需要尽可能少地中断计数器翻转。并通过在最后收集最终计数器值。(软件可以随时读取/写入精确计数;这就是内核在上下文切换时虚拟化计数器的方式。)这可能是对一些细节的简化,但据我所知,准确地解释了为什么perf stat
基本上没有开销并且能够提供非常精确和可重复的计数。但是,
perf record
通过样本文件和用于n
收集它们的数据,只能从中推断出总计数samples * n
,因此是“大约”。脚注 1:PEBS 缓冲区通常非常小,例如 1 个样本,因此它不会节省太多/根本不节省中断,但它确实将样本精确地归因于一条指令,而不是附近的一条指令:请参阅https://www.brendangregg.com/perf.html中的 skids 和 PEBS 部分。非常适合像这样的事件
mem_load_retired.l3_miss
。像这样的事件cycles
仍然必须选择一条指令来“责备”,这通常是等待缓慢输入的指令,例如试图使用缓存未命中加载结果的指令,而不是加载本身。顺便说一句,
:u
/:k
过滤器仅在用户空间或内核空间中计数是硬件支持的。因此内核不必管理每个中断上的计数器。(事实上,内核不必管理计数器,因此如果您不使用:u
或,您的分析将包括您的任务在核心上--all-user
时运行的中断处理程序。)current