性能如何与function相关联?

更确切地说,perf工具如何将PMU事件与函数联系起来,我已经意识到,当内核perf子系统logging事件计数器时,它还会logging程序计数器(PC),以便将计数与函数相关联。

但是要真正得到好的结果,你需要以很高的速率对计数器进行采样,否则你可能会把计数器与一组函数关联起来。 但是读取计数器并将采样数据(计数器,PC,调用堆栈)写入perf mmap空间是非常具有侵入性的。

我在一些消息来源读到,这种采样只发生在PMU计数器溢出时,但这可能是非常粗糙的,除非我设置计数器很快溢出

我在这里错过了什么?

perf record是统计分析工具 ,它要么编程硬件性能事件监视单元(PMU)溢出一些计数(例如-e cycles -c 1000000写-1000000计数器并启用计数循环;使用-F或不频率/周期参数它将自动调整值),溢出中断性能将重新编程它的下一个计数。 所以每秒钟会有几百或几千个事件。 或者可以使用OS定时器中断( -e task-clock )来获取定期采样。 在每个样本上(或从硬件PMU中断)perf将记录当前PC(EIP)和/或调用堆栈; 并不记录当前计数器的值(使用perf scriptperf 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.ccmd_report / __cmd_report > perf_session__process_events – >一些魔术 – > process_sample_event记录perf.data中的所有ip (PC)值hist_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]++; 

然后它会输出收集的直方图report__browse_hists – > perf_evlist__tty_browse_hists – > hists__fprintf_nr_sample_events(hists, rep, evname, stdout);

每个样本都已经与确切的功能相关联(由于CPU的乱序性和不精确的PMU溢出事件,其内部的位不精确指令),这就是统计分析工作的原因 。 当程序运行时间较短(小于秒)和/或采样频率太低时, perf.data可能记录的样本perf.data 。 但是如果你有超过几百个样本,你可以找到大多数cpu占用的函数(它们可能有pareto规则 ,运行时间大约是几十个百分点的程序运行时间,当你想看到更小的函数时(大约有几个运行时间),使用数千或数十个或数千个样本,并进行一些统计估计(当您有100或1000个样本时,您将无法获得以0.1%的时间运行的正确百分比函数)。