perf.data 到文本或 csv

perf.data to text or csv

我正在使用 'perf record' 命令以 1 毫秒对硬件计数器进行采样。它为我提供了一个 'perf.data' 作为输出文件,但我不知道有任何 tool/command 可以帮助我将计数器数据从 'perf.data' 二进制文件读取到文本或 CSV 文件中。或者简单地说,我需要每隔 1ms 从 'perf.data' 文件中读取硬件计数器事件数据。

更多详细信息:

  1. 我已经使用'perf stat'命令以10ms获取硬件计数器事件数据,但它不允许以小于10ms的采样间隔进行采样。所以,我使用 'perf record' 而不是 perf stat 在 1ms 采样。 一些有用的 link 说服我使用 perf record: Collecting the data for a partiulcar process from PMU for every 1 milli second

  2. 我也试过'perf script'但是它只提供了一些硬件事件的支持。例如:缓存事件不受 perf 脚本支持。 link: Can't sample hardware cache events with linux perf

有人可以帮我解决这个问题吗?请假设我知道如何使用 perf record 命令并且已经有了 perf.data 文件(从 perf record 生成)

已编辑:以下是使用答案反馈的命令及其在终端上的输出消息:

1) perf record -e LLC-stores,LLC-loads,cache-misses -F 999 -R -T ls>ls.txt

输出:

[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.017 MB perf.data (28 samples) ]

2) perf report -F sample,period --stdio

输出:

Total Lost Samples: 0
Samples: 9  of event 'LLC-stores'
Event count (approx.): 7440
     Samples        Period
............  ............
         9          7440

Samples: 9  of event 'LLC-loads'
Event count (approx.): 50008
     Samples        Period
............  ............
         9         50008

Samples: 10  of event 'cache-misses'
Event count (approx.): 351826
     Samples        Period
............  ............
        10        351826

3) perf script -F period,event

输出:

     1   LLC-stores: 
     1    LLC-loads: 
     1 cache-misses: 
     1    LLC-loads: 
     1 cache-misses: 
    61    LLC-loads: 
    58 cache-misses: 
  3097 cache-misses: 
     1   LLC-stores: 
    13   LLC-stores: 
  4748    LLC-loads: 
  1390   LLC-stores: 
190186 cache-misses: 
     1   LLC-stores: 
     1    LLC-loads: 
     1 cache-misses: 
     1    LLC-loads: 
     1 cache-misses: 
     1   LLC-stores: 
    52 cache-misses: 
    50    LLC-loads: 
    20   LLC-stores: 
  4110 cache-misses: 
  2002    LLC-loads: 
   748   LLC-stores: 
154319 cache-misses: 
 43143    LLC-loads: 
  5265   LLC-stores: 

4) perf stat -I 1 -e LLC-stores,LLC-loads,cache-misses ls>ls.txt

输出:

       time             counts unit events
 0.006476856              1,115      LLC-stores
 0.006476856             13,121      LLC-loads
 0.006476856              9,371      cache-misses

perf reportperf script 都提供样本数、周期和事件名称,但不提供每个样本的事件计数。如果您能告诉我如何获取我们从性能记录中获取的每 28 个样本的事件计数,那将非常有帮助。

您应该使用 perf record -e <event-name> ... 每 1 毫秒采样一次事件。您似乎正在尝试读取 perf.data 文件并将其组织成人类可读的数据。如果您不知道,您应该使用 perf reportperf report 命令读取 perf.data 文件并生成简明的执行配置文件。下面的link应该对你有帮助-

Sample analysis with perf report

您可以根据需要修改 perf report 输出。您还可以使用 perf report -F 以 csv 格式指定多个列。

但是,此外,perf stat 确实有一种机制可以使用 perf stat -x 命令以 csv 格式收集信息。

编辑#1:

(我正在使用 Linux-Kernel 4.14.3 进行评估。)

由于您想要获取每个样本的事件数,因此有几点需要注意。要计算每个样本的事件数,您需要知道采样周期。采样周期为您提供事件数,之后性能计数器将溢出并且内核将记录一个样本。所以基本上,在你的情况下,

sampling period = number of events per sample

现在有两种方法可以指定这个采样周期。要么指定,要么不指定。

如果在执行 perf record 时,您指定采样周期.. 像这样:-

perf record -e <some_event_name> -c 1000 ...

这里-c 1000表示采样周期为1000,这种情况下,你故意强制系统每个样本记录1000个事件,因为采样周期是你固定的。

另一方面,如果您不指定采样周期,系统将尝试以默认频率 1000 samples/sec 记录事件。这意味着系统将在需要时自动更改采样周期,以保持 1000 samples/sec 的频率。在这种情况下,要确定采样周期,您需要观察perf.data文件。

具体来说,您需要使用以下命令打开 perf.data 文件:

perf script -D

输出看起来像这样:-

0 0 0x108 [0x38]: PERF_RECORD_FORK(1:1):(0:0)

0x140 [0x30]: event: 3
.
. ... raw event: size 48 bytes
.  0000:  03 00 00 00 00 00 30 00 01 00 00 00 01 00 00 00  ......0.........
.  0010:  73 79 73 74 65 6d 64 00 00 00 00 00 00 00 00 00  systemd.........
.  0020:  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

0 0 0x140 [0x30]: PERF_RECORD_COMM: systemd:1/1

0x170 [0x38]: event: 7
.
. ... raw event: size 56 bytes
.  0000:  07 00 00 00 00 00 38 00 02 00 00 00 00 00 00 00  ......8.........
.  0010:  02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
.  0020:  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
.  0030:  00 00 00 00 00 00 00 00                          ........ 

您可以看到不同类型的记录,例如 PERF_RECORD_FORKPERF_RECORD_COMM,甚至 PERF_RECORD_MMAP。您需要特别注意文件中以 PERF_RECORD_SAMPLE 开头的记录。像这样:

14 173826354106096 0x10d40 [0x28]: PERF_RECORD_SAMPLE(IP, 0x1): 28179/28179: 0xffffffffa500d3b5 period: 3000 addr: 0
 ... thread: perf:28179
 ...... dso: [kernel.kallsyms]
            perf 28179 [014] 173826.354106: cache-misses:  ffffffffa500d3b5 [unknown] ([kernel.kallsyms])

如您所见,在这种情况下,周期为 3000,即在前一个采样事件和本次采样事件之间收集的事件数为 3000。(即每个样本的事件数为 3000)请注意,正如我提到的高于这个时期可能会被调整。因此,您需要从 perf.data 文件中收集所有 PERF_RECORD_SAMPLE 记录。