linux - 在 `perf stat` 的输出上运行 `perf record` ?

标签 linux performance optimization perf

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

我可以在 perf record 的输出上运行 perf stat 吗?这样我既可以查看 perf 记录的数据,又可以得到一个简单的概览?

最佳答案

perf stat 在计数模式下使用 hardware performance monitoring unitperf record/perf report with perf.data 文件在溢出模式下使用相同的单元。在这两种模式下,hardware performance counters 都通过控制寄存器配置为某种性能事件(例如 cpu 周期或执行的指令),并且计数器将在每个事件上递增。

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

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

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

$ 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 中,并且使用了默认的硬件事件(周期)

$ 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 内容:

$ 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-8.25 亿):

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

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

$ 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

所以,你 can't run perf stat on perf.data file ,但你可以要求 perf report 打印带有事件计数估计的标题。您也可以尝试从 perf script/perf script -D 解析时间戳。

关于linux - 在 `perf stat` 的输出上运行 `perf record` ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62550369/

相关文章:

java - 如何获取WiFi网络接口(interface)的MAC地址?

php - 查找/检测/格式化周围文件中使用的 GetText 字符串

regex - 日志提取: SED Command

c - 如何检测我是否是第一个实例或向同一应用程序的前一个实例发送 IPC 消息?

typing - 如何更快地打字

JavaFX(八)——提高散点图性能

performance - 尝试实现类似 XMPP 的协议(protocol)的 IIS 性能问题

javascript - 在 JavaScript 中比较字符串的最佳方法?

php - 如何优化这个复杂的 MySql 查询

c# - 连接字符串的最有效方法?