关于linux:在`perf record`的输出上运行`perf stat`吗?

run `perf stat` on the output of `perf record`?

使用perf(Linux Profiler)(v4.15.18),我可以运行perf stat $COMMAND来获取命令的一些简单统计信息。 如果运行perf record,它会将大量数据保存到perf.data文件中。

我可以在perf record的输出上运行perf stat吗? 这样我就可以查看性能记录中的数据,还可以得到一个简单的概述?


perf stat在计数模式下使用硬件性能监视单元,而perf record / perf report与perf.data文件在溢出模式下使用相同的单元。在两种模式下,硬件性能计数器都通过控制寄存器配置成某种性能事件(例如,CPU周期或执行的指令),并且计数器将在每个事件时递增。

在计数模式下,perf stat将在程序启动时将计数器配置为零,并在程序退出时读取最终计数器值(实际上,计数可能会分成几个段,结果相同-单个值表示完整运行)。

在分析模式(采样分析)中,perf record将计数器配置为某个负值,例如-100000,并且将安装溢出处理程序(实际值将自动调整为某个频率)。每100000个事件,计数器将溢出为零并产生一个中断。 perf_events中断处理程序会将"样本"(当前时间,pid,指令指针,还可以选择-g中的调用堆栈)记录到环形缓冲区中,然后将其保存到perf.data中。该处理程序还将再次将计数器重置为-100000。因此,运行足够长的时间后,将有成千上万个样本存储在perf.data中,这些样本可用于生成程序的统计资料(程序的哪些部分更频繁地运行)。

perf stat显示什么?在x86_64 cpu的默认模式下:程序的运行时间(任务时钟和运行时间),3个软件事件(上下文切换,cpu迁移,页面错误),4个硬件计数器:循环,指令,分支,分支未命中:

1
2
3
4
5
6
7
8
9
10
11
12
$ echo '3^123456%3' | perf stat bc
0
 Performance counter stats for 'bc':
        325.604672      task-clock (msec)         #    0.998 CPUs utilized          
                 0      context-switches          #    0.000 K/sec                  
                 0      cpu-migrations            #    0.000 K/sec                  
               181      page-faults               #    0.556 K/sec                  
       828,234,675      cycles                    #    2.544 GHz                    
     1,840,146,399      instructions              #    2.22  insn per cycle        
       348,965,282      branches                  # 1071.745 M/sec                  
        15,385,371      branch-misses             #    4.41% of all branches        
       0.326152702 seconds time elapsed

记录perf record是什么?在单个唤醒事件(环形缓冲区溢出)中,确实将1246个样本保存到perf.data中,并且使用了默认的hw事件(周期)

1
2
3
$ echo '3^123456%3' | perf record bc
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.049 MB perf.data (1293 samples) ]

使用perf report --header|lessperf scriptperf script -D,您可以查看perf.data内容:

1
2
3
4
5
$ perf report --header |grep event
# event : name = cycles:uppp, , size = 112, { sample_period, sample_freq } = 4000, sample_type = IP|TID|TIME|PERIOD ...
# Samples: 1K of event 'cycles:uppp'
$ perf script 2>/dev/null |grep cycles|wc -l
1293

perf.data中有一些时间戳,还有一些用于程序启动和退出的其他事件(perf script -D |egrep exec\\|EXIT),但是默认perf.data中没有足够的信息来完全重建perf stat输出。运行时间仅记录为开始和退出的时间戳,并且在每个事件示例中,均不记录软件事件,仅使用单个硬件事件(周期;无指令,分支,分支未命中)。可以对用过的硬件计数器进行近似估算,但并不精确(实际周期约为820-825百万):

1
2
$ perf report --header |grep Event
# Event count (approx.): 836622729

使用perf.data的非默认记录,可以估计更多事件:

1
2
3
4
5
6
7
8
9
10
11
$ echo '3^123456%3' | perf record -e cycles,instructions,branches,branch-misses bc
[ perf record: Captured and wrote 0.238 MB perf.data (5164 samples) ]
$ perf report --header |egrep Event\\|Samples
# Samples: 1K of event 'cycles'
# Event count (approx.): 834809036
# Samples: 1K of event 'instructions'
# Event count (approx.): 1834083643
# Samples: 1K of event 'branches'
# Event count (approx.): 347750459
# Samples: 1K of event 'branch-misses'
# Event count (approx.): 15382047

因此,您不能在perf.data文件上运行perf stat,但是可以要求perf report打印带有事件计数估计的标题。您也可以尝试从perf script / perf script -D解析时间戳。


不,你不能。性能记录输出是一个数据文件。性能统计期望应用程序。
您可以使用perf脚本运行预定义的脚本,以汇总和汇总跟踪数据。可以使用以下命令列出可能的脚本。
性能脚本-l
除了数量有限的预定义脚本之外,您还可以在python或perl中定义自定义perf.data处理脚本。
有关详细信息,请参见perf脚本,python中的perf脚本和perl中的perf脚本。