有没有办法在linux中定期读取性能计数器?
像perf stat
这样能够对每个X周期进行采样的东西就是我正在寻找的。 p>
基本上我希望能够为某些程序每X量的cpu周期读取指令计数器(执行的指令数)。
答案 0 :(得分:6)
好消息:在下一个内核(Linux 3.9)中,perf stat将有一个选项-I msecs
以定期打印事件增量。
https://patchwork.kernel.org/patch/2004891/
$ perf stat -I 1000 -e cycles noploop 10 noploop for 10 seconds 1.000086918 2385155642 cycles # 0.000 GHz 2.000267937 2392279774 cycles # 0.000 GHz 3.000385400 2390971450 cycles # 0.000 GHz 4.000504408 2390996752 cycles # 0.000 GHz 5.000626878 2390853097 cycles # 0.000 GHz
http://man7.org/linux/man-pages/man1/perf-stat.1.html
-I msecs, --interval-print msecs
每N毫秒打印计数增量(最小值:10毫秒)
答案 1 :(得分:5)
Linux中的perf工具似乎是在计数器达到特定值时记录事件,而不是定期采样。
命令perf record -e cycles,instructions -c 10000
每10000个周期和每10000个指令存储一个事件。它可以针对新命令或现有pid运行。它记录到当前目录中的perf.data
。
分析数据是另一回事。使用perf script
让你非常接近:
ls 16040 2152149.005813: cycles: c113a068 ([kernel.kallsyms])
ls 16040 2152149.005820: cycles: c1576af0 ([kernel.kallsyms])
ls 16040 2152149.005827: cycles: c10ed6aa ([kernel.kallsyms])
ls 16040 2152149.005831: instructions: c1104b30 ([kernel.kallsyms])
ls 16040 2152149.005835: cycles: c11777c1 ([kernel.kallsyms])
ls 16040 2152149.005842: cycles: c10702a8 ([kernel.kallsyms])
...
您需要编写一个脚本,该脚本从该输出中获取一串行,并计算该集合中“周期”和“指令”事件的数量。您可以通过更改录制命令中的参数-c 10000
来调整分辨率。
我通过针对perf stat
运行perf record
和ls /
来验证分析。 Stat报告了2 634 205个周期,1 725 255个指令,而脚本输出具有410个周期事件和189个指令事件。 -c
值越小,循环读数中的开销就越大。
-F
还有一个perf record
选项,会定期进行采样。但是,在使用此选项时,我找不到检索计数器值的方法。
编辑: perf stat
显然也适用于pids,并捕获数据直到按下ctrl-c。修改源应该很容易,因此它总是捕获N秒,然后循环运行。
答案 2 :(得分:0)
您可以轻松修改perf stat来执行此操作。
事实上,我已经实施了粗略的修改,并很乐意与您分享这一变化..
我所做的更改主要是在while(!done)循环中的run_perf_stat函数中
只需将while(!done){sleep(1);}下面的线移到循环内部,然后将睡眠时间改为纳米睡眠状态,以及您想要采样的时间段
那应该在STDOUT(或STDERR)上打印输出
如果你想存储这些值,我建议你创建一个struct stats类型的二维数组,用每个样本更新它并定期写入文件