Str*_*dle 2 linux performance linux-kernel perf
更准确地说,perf 工具如何将 PMU 事件与函数关联起来,我已经意识到,当内核 perf 子系统记录事件计数器时,它还会记录程序计数器 (PC),因此它可以将计数与函数关联起来。
然而,要真正获得细粒度结果,您需要以非常高的速率对计数器进行采样,否则您可能会将计数器与一组函数相关联。但是读取计数器并将采样数据(计数器、PC、调用堆栈)写入 perf mmap 空间是非常侵入性的。
我在一些资料中读到,这种采样仅在 PMU 计数器溢出时发生,但这可能非常粗糙,除非我将计数器设置为非常快地溢出
我在这里缺少什么?
perf record是统计分析工具,它可以对硬件性能事件监视器单元 (PMU) 进行编程,使其在一定次数的计数后溢出(例如,使用-e cycles -c 1000000写入 -1000000 来计数器并启用计数周期;无论有-F或没有频率/周期参数,它都会自动调整值),发生溢出中断时,perf 将为下一次计数重新编程。因此每秒会有数百或数千个事件。或者它可以使用操作系统定时器中断(-e task-clock)来获取周期性样本。在每个样本上(或在来自硬件 PMU 的中断上),perf 将记录当前的 PC (EIP) 和/或调用堆栈;并且它不记录计数器的当前值(使用perf script或perf script -D检查存储在 perf.data 中的数据的完整转储;或示例事件转储的代码- 有sample->ip但没有 PMU 的当前计数)。
perf report将解析 perf.data 以获取其中记录的所有 PC。它将计算每台 PC 被采样多少次以构建直方图[PC] -> sample_count。每台 PC 都将与其所属的确切功能相关联(perf 报告将解析内存映射,因为mmap事件也记录在 perf.data 中,打开每个使用的二进制文件,查找每个二进制文件的符号表)。
实际代码perf report位于linux/tools/perf/builtin-report.c:cmd_report/ __cmd_report-> perf_session__process_events-> 一些魔法 ->将 perf.data (PC) 值process_sample_event中提到的所有值记录到直方图中:iphist_entry_iter__add(&iter, &al, rep->max_stack, rep);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]++;
Run Code Online (Sandbox Code Playgroud)
然后它将通过report__browse_hists-> perf_evlist__tty_browse_hists->输出收集的直方图hists__fprintf_nr_sample_events(hists, rep, evname, stdout);。
每个样本都已经与精确的函数相关联(由于 CPU 的无序性质和不精确的 PMU 溢出事件,其中的位不精确指令),这就是统计分析的工作原理。当您的程序运行时间短(小于秒)和/或采样频率太低时,您可能在perf.data. 但是,如果您有超过数百个样本,您可以找到大多数 cpu 密集型函数(它们可能具有帕累托规则,并且运行时间大约占程序运行时间的百分之几十。当您想查看较小的函数时(大约占运行时间的百分之几) ),使用数千或数十或数千个样本并进行一些统计估计(当您有 100 或 1000 个样本时,您将无法获得运行 0.1% 时间的函数的正确百分比)。
| 归档时间: |
|
| 查看次数: |
2447 次 |
| 最近记录: |