- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
更准确地说,perf 工具如何将 PMU 事件关联到函数我已经意识到,当内核 perf 子系统记录事件计数器时,它还会记录程序计数器 (PC),因此它可以将计数与函数相关联。
然而,要真正获得精细的结果,您需要以非常高的速率对计数器进行采样,否则您可能会将计数器与一组函数相关联。但是读取计数器并将采样数据(计数器、PC、调用堆栈)写入 perf mmap 空间是非常具有侵入性的。
我在一些资料中读到这种采样仅在 PMU 计数器溢出时发生,但这可能非常粗糙,除非我将计数器设置为非常快地溢出
我在这里错过了什么?
最佳答案
perf record
是statistical profiling tool ,它要么将硬件性能事件监控单元 (PMU) 编程为在一定数量的计数后溢出(例如使用 -e cycles -c 1000000
将 -1000000 写入计数器并启用计数周期;使用 -F
或没有 freq/period 参数,它将自动调整值),溢出中断 perf 将为下一次计数重新编程。所以它每秒会有几百或几千个事件。或者它可以使用 OS 定时器中断 (-e task-clock
) 来获取周期性样本。在每个样本(或来自硬件 PMU 的中断)上,perf 将记录当前 PC(EIP)和/或调用堆栈;并且它不记录计数器的当前值(使用 perf script
or perf script -D
检查存储在 perf.data 中的数据的完整转储;或 code of sample event dumping - 有 sample->ip
但不是 PMU 的当前计数).
perf report
将解析 perf.data 以获取其中记录的所有 PC。它将计算每台 PC 被采样的次数以构建直方图 [PC] -> sample_count
。每台 PC 都将与其所属的确切功能相关联(perf report 将解析内存映射,因为 mmap
事件也记录在 perf.data 中,打开每个使用的二进制文件,找到每个二进制文件的符号表)。
perf report
的实际代码在 linux/tools/perf/builtin-report.c
中:cmd_report
/__cmd_report
-> perf_session__process_events
-> 一些魔法 -> process_sample_event
使用 hist_entry_iter__add(&iter, &al, rep->max_stack, rep);
将 perf.data ip
(PC) 中提到的所有值记录到带有 hist_iter__report_callback
的直方图中:
hist_entry__inc_addr_samples(he, evsel->idx, al->addr);
. . . (perf/util/annotate.c) __symbol__inc_addr_samples
611 h->addr[offset]++;
然后它将输出收集到的直方图 report__browse_hists
-> perf_evlist__tty_browse_hists
-> hists__fprintf_nr_sample_events(hists, rep, evname, stdout);
。
每个样本都已经与精确的函数相关联(由于 CPU 的乱序特性和不精确的 PMU 溢出事件,其中的位不精确指令),这就是 statistical profiling works 的方式.当您的程序运行时间很短(少于一秒)和/或采样频率太低时,perf.data
中记录的样本可能很少。但是如果你有数百个以上的样本,你可以找到大多数 cpu-heavy 函数(它们可能有 pareto rule 并且运行大约百分之几十的程序运行时间。当你想看到更小的函数(大约百分之几的运行时间时间),使用数千或数十或数千个样本并进行一些统计估计(当您有 100 或 1000 个样本时,您将无法获得运行时间为 0.1% 的正确函数百分比)。
关于linux - perf 如何将事件关联到函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42246265/
我是一名优秀的程序员,十分优秀!