似乎perf stat --cpu=
的文档是错误的或具有误导性的,当他们说The 101 option is still necessary to activate system-wide monitoring.
无论有没有-a
,它的行为似乎都是一样的,所以计数来自其他进程,如GUI动画,光标闪烁等,或者对于cycles:k
,来自任何中断处理程序,无论哪个进程是该核心上的内核current
.
我在Arch GNU/Linux系统上用内核和perf 6.5测试了这个. 这里的确凿证据是运行另一个固定在不同核心上的无限循环进程,并且在该核心上看到cycles:u
,这与运行来自perf命令行的命令的核心相同.
基线without任何时髦的选项,其中awk 'BEGIN{for(i=0;i<100000000;i++){}}'
是要分析的命令.(它使CPU核心忙碌几秒钟,除了在启动和退出时不进行任何系统调用,并且具有很小的缓存占用.)
$ taskset -c 1 perf stat -e task-clock,cycles:u --delay=1000 awk 'BEGIN{for(i=0;i<100000000;i++){}}'
Events disabled
Events enabled
Performance counter stats for 'awk BEGIN{for(i=0;i<100000000;i++){}}':
2,625.29 msec task-clock # 1.000 CPUs utilized
10,226,974,370 cycles:u
2.625290561 seconds time elapsed
与--cpu
相比,有两个迹象表明它不会局限于awk
进程:任务时钟比运行时间长8倍.它打印的标题是:Performance counter stats for 'CPU(s) 0-7':,而不是我们的进程.
taskset -c 1 perf stat -e task-clock,cycles:u --cpu=0-7 --delay=1000 awk 'BEGIN{for(i=0;i<100000000;i++){}}'
Events disabled
Events enabled
Performance counter stats for 'CPU(s) 0-7':
23,621.12 msec task-clock # 8.000 CPUs utilized
12,747,549,694 cycles:u
2.952544251 seconds time elapsed
由于-A
又称为--no-aggr
不是跨CPU聚合,所以每个CPU都有任务时钟在整个时间间隔内运行,即使我们的进程肯定不在上面(因为它和Perf本身开始固定在CPU 1上):
$ taskset -c 1 perf stat -e task-clock,cycles:u --cpu=0-7 -A --delay=1000 awk 'BEGIN{for(i=0;i<100000000;i++){}}'
Events disabled
Events enabled
Performance counter stats for 'CPU(s) 0-7':
CPU0 2,605.76 msec task-clock # 1.000 CPUs utilized
CPU1 2,605.75 msec task-clock # 1.000 CPUs utilized
CPU2 2,605.76 msec task-clock # 1.000 CPUs utilized
CPU3 2,605.75 msec task-clock # 1.000 CPUs utilized
CPU4 2,605.78 msec task-clock # 1.000 CPUs utilized
CPU5 2,605.78 msec task-clock # 1.000 CPUs utilized
CPU6 2,605.78 msec task-clock # 1.000 CPUs utilized
CPU7 2,605.78 msec task-clock # 1.000 CPUs utilized
CPU0 162,311,044 cycles:u
CPU1 10,153,813,410 cycles:u
CPU2 12,114,460 cycles:u
CPU3 49,619,566 cycles:u
CPU4 180,412,777 cycles:u
CPU5 51,045,799 cycles:u
CPU6 132,275,644 cycles:u
CPU7 344,942,273 cycles:u
2.605703012 seconds time elapsed
对于虚拟加载(就像另一个awk进程,或者在本例中,我运行的程序只在pause
条指令上循环,除了使用更少的功率之外,这并不是什么特别的),我们看到它使用的核心CPU 2与CPU 1上的awk
一样多.
$ taskset -c 2 timeout 10m ~/src/SO/pauseloop &
# actually on another terminal
$ taskset -c 1 perf stat -e task-clock,cycles:u --cpu=0-7 -A --delay=1000 awk 'BEGIN{for(i=0;i<100000000;i++){}}'
Events disabled
Events enabled
Performance counter stats for 'CPU(s) 0-7':
CPU0 2,721.71 msec task-clock # 1.000 CPUs utilized
CPU1 2,721.71 msec task-clock # 1.000 CPUs utilized
CPU2 2,721.71 msec task-clock # 1.000 CPUs utilized
CPU3 2,721.71 msec task-clock # 1.000 CPUs utilized
CPU4 2,721.70 msec task-clock # 1.000 CPUs utilized
CPU5 2,721.70 msec task-clock # 1.000 CPUs utilized
CPU6 2,721.69 msec task-clock # 1.000 CPUs utilized
CPU7 2,721.69 msec task-clock # 1.000 CPUs utilized
CPU0 861,492,255 cycles:u
CPU1 10,485,755,009 cycles:u
CPU2 10,485,655,861 cycles:u
CPU3 559,708,162 cycles:u
CPU4 1,207,134,025 cycles:u
CPU5 556,142,162 cycles:u
CPU6 623,020,558 cycles:u
CPU7 3,721,131,901 cycles:u
2.721620976 seconds time elapsed
请注意,在内核1和内核2上,cycles:u
的计数分别为10,485,755,009
和10,485,655,861
.每10k不超过1个部分也是如此.(在我的i7-6700k上,频率为3.9 GHz,绝对差异约为10,485,755,009
万,即约250纳秒,这很容易解释为不同内核的启动/停止计数的差异.)
-a --cpu
only changes the header message, not counts
将-a
加到其中任何一个上(不带--cpu
的除外),除了头消息外什么都不会改变,变为Performance counter stats for 'system wide':而不是'CPU(s) 0-7'
我看到的一切都与--cpu
一致,实际上计算的是perf stat
正在运行的核心上发生的一切,就像-a
模式一样.