我对perf record和perf stat之间的区别感到困惑,当涉及到计算诸如页面错误、缓存丢失和perf list中的任何其他事件时。我在“问题1”的答案下面有两个问题,可能也有助于回答“问题2”,但如果没有,我会把它们明确地写出来。
问题1:我的理解是,perf stat得到计数的“摘要”,但是当与-I选项一起使用时,会在指定的毫秒间隔内获取计数。使用这个选项,它是对间隔上的计数进行求和,还是得到间隔上的平均值,还是其他什么东西呢?我想应该是总结出来的。perf维基声明它是聚合的,但我想这可能意味着两者之一。
问题2:为什么perf stat -e <event1> -I 1000 sleep 5不给出相同的计数,就像我对下面的命令perf record -e <event1> -F 1000 sleep 5每秒钟的计数进行汇总一样?
例如,如果我使用“页面错误”作为event1的事件,我将在下面的每个命令下得到以下输出。(我假设句号字段是perf record的perf.data文件中事件的计数)
PERF统计
perf stat -e page-faults -I 1000 sleep 5
# time counts unit events
1.000252928 54 page-faults
2.000498389 <not counted> page-faults
3.000569957 <not counted> page-faults
4.000659987 <not counted> page-faults
5.000837864 2 page-faultsPERF记录
perf record -e page-faults -F 1000 sleep 5
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.016 MB perf.data (6 samples) ]
perf script -F period
1
1
1
5
38
164我希望,如果我从perf stat中将计数相加,我将得到与perf record相同的总和。如果我将-c选项与perf record一起使用,并给出参数为1的参数,那么我确实得到了一个接近匹配的结果。这仅仅是因为页面错误相对较少而造成的巧合吗?
我迄今使用的参考资料:
提前感谢您所能提供的所有洞察力。
发布于 2018-03-11 16:37:01
首先,使用sleep和page-faults的测试用例并不是理想的测试用例。在睡眠期间不应该发生页面错误事件,您不能真正期待任何有趣的事情。为了便于推理,我建议使用ref-cycles (硬件)事件和繁忙的工作负载(如awk 'BEGIN { while(1){} }' )。
问题1:我的理解是perf获得计数的“摘要”,但与-I选项一起使用时,将在指定的毫秒间隔内获取计数。使用这个选项,它是对间隔上的计数进行求和,还是得到间隔上的平均值,还是其他什么东西呢?我想应该是总结出来的。
是。这些数值只是总结一下而已。您可以通过测试来确认这一点:
$ perf stat -e ref-cycles -I 1000 timeout 10s awk 'BEGIN { while(1){} }'
# time counts unit events
1.000105072 2,563,666,664 ref-cycles
2.000267991 2,577,462,550 ref-cycles
3.000415395 2,577,211,936 ref-cycles
4.000543311 2,577,240,458 ref-cycles
5.000702131 2,577,525,002 ref-cycles
6.000857663 2,577,156,088 ref-cycles
[ ... snip ... ]
[ Note that it may not be as nicely consistent on all systems due dynamic frequency scaling ]
$ perf stat -e ref-cycles -I 3000 timeout 10s awk 'BEGIN { while(1){} }'
# time counts unit events
3.000107921 7,736,108,718 ref-cycles
6.000265186 7,732,065,900 ref-cycles
9.000372029 7,728,302,192 ref-cycles 问题2:为什么
perf stat -e <event1> -I 1000 sleep 5不给出相同的计数,就像我对下面的命令perf record -e <event1> -F 1000 sleep 5每秒钟的计数进行汇总一样?
perf stat -I以毫秒为单位,而perf record -F为HZ (1/s),因此perf stat -I 1000的对应命令是perf record -F 1。事实上,由于我们更稳定的事件/工作负载,这看起来更好:
$ perf stat -e ref-cycles -I 1000 timeout 10s awk 'BEGIN { while(1){} }'
# time counts unit events
1.000089518 2,578,694,534 ref-cycles
2.000203872 2,579,866,250 ref-cycles
3.000294300 2,579,857,852 ref-cycles
4.000390273 2,579,964,842 ref-cycles
5.000488375 2,577,955,536 ref-cycles
6.000587028 2,577,176,316 ref-cycles
7.000688250 2,577,334,786 ref-cycles
8.000785388 2,577,581,500 ref-cycles
9.000876466 2,577,511,326 ref-cycles
10.000977965 2,577,344,692 ref-cycles
10.001195845 466,674 ref-cycles
$ perf record -e ref-cycles -F 1 timeout 10s awk 'BEGIN { while(1){} }'
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.008 MB perf.data (17 samples) ]
$ perf script -F time,period
3369070.273722: 1
3369070.273755: 1
3369070.273911: 3757
3369070.273916: 3015133
3369070.274486: 1
3369070.274556: 1
3369070.274657: 1778
3369070.274662: 2196921
3369070.275523: 47192985748
3369072.663696: 2578692405
3369073.663547: 2579122382
3369074.663609: 2580015300
3369075.664085: 2579873741
3369076.664433: 2578638211
3369077.664379: 2578378119
3369078.664175: 2578166440
3369079.663896: 2579238122 所以你看,最终的结果对于perf record -F来说也是稳定的。不幸的是,perf record的文档非常糟糕。通过查看底层系统调用-c的文档,您可以了解man perf_event_open和man perf_event_open设置的含义。
sample_period,sample_freqA“取样”事件是一个在每N个事件中生成溢出通知的事件,其中N是由sample_period提供的。抽样事件的sample_period> 0。当发生溢出时,请求的数据将记录在mmap缓冲区中。sample_type字段控制在每个溢出上记录的数据。 如果您希望使用频率而不是周期,可以使用sample_freq。在这种情况下,您设置了freq标志。内核将调整采样周期以达到期望的速率。的调整速度是一个定时器滴答。
因此,当perf stat使用内部计时器每毫秒读取计数器的值时,perf record设置一个事件溢出计数器以获取每个-c事件的示例。这意味着它需要每个N事件(例如,每个N、page-fault或cycles)样本。使用-F,它试图调节这个溢出值以达到所需的频率。它尝试不同的值,并相应地调整它的上下。这最终适用于速率稳定的计数器,但对于动态事件将得到不稳定的结果。
https://stackoverflow.com/questions/49216628
复制相似问题