收集统计数据

收集统计数据

我编写了一个简单的程序,其中有一个在 CPU 核心上运行的线程。它旋转得有点激进,并且占用了 100% 的 CPU 核心。我可以用top+看到这一点1

N分钟后,我希望能够知道:

内核抢占(中断)我正在运行的线程多少次?

答案1

这就是 Linux 事件挂钩的用途,您可以将它们与perf

收集统计数据

我会从简单的事情开始:

sudo perf state -e sched:sched_switch yourprogram 

尝试这个:

busyloop.c

#include <stdint.h>
int main()
{
    for (volatile uint_fast64_t i = 0; i < (1ULL<<34); ++i) {
    }
}

编译:

gcc -O3 -o busyloop busyloop.c

跑步:

$ sudo perf stat -e sched:sched_switch ./busyloop

 Performance counter stats for './busyloop':

               134      sched:sched_switch

      26.534402995 seconds time elapsed

      26.496337000 seconds user
       0.000996000 seconds sys

这就是你的答案——差不多吧。这就是日程安排切换的时间。这确实包括您的进程本身进入内核,而不是被中断。

sched_switch减去指定两者和系统调用输入计数时得到的数字:

$ sudo perf stat -e sched:sched_switch,raw_syscalls:sys_enter ./busyloop

 Performance counter stats for './busyloop':

               765      sched:sched_switch
                30      raw_syscalls:sys_enter

      26.528107216 seconds time elapsed

      26.473054000 seconds user
       0.002994000 seconds sys

在这个负载较多的示例运行中,有 765 次上下文切换,但其中只有 30 次是由进程自身执行系统调用引起的。

实时统计

perf stat通常也可以使用相同的命令行选项来实时观察可以做什么perf top

./busyloop &
sudo perf top -e sched:sched_switch,raw_syscalls:sys_enter -p $!

perf top,,,没有任何指定的事件来观察,做一些非常了不起的事情 - 他们在或多或少的定期采样中观察您的 CPU 核心在哪个功能中的频率。这是在实际工作负载情况下优化软件和系统的出色perf record第一步perf report但这会导致很远的事情!)

深度追踪

如果你想要一些非常详细的东西,perf sched这是一个令人惊讶的强大工具。

$ # make a recording
$ sudo perf sched record -- ./busyloop
[ perf record: Woken up 75 times to write data ]
[ perf record: Captured and wrote 161,058 MB perf.data (1458691 samples) ]
$ # evaluate the recording
$ sudo perf sched map
  *A0                               179778.272339 secs A0 => migration/0:17
  *.                                179778.272347 secs .  => swapper:0
   .  *B0                           179778.272413 secs B0 => migration/1:21
   .  *.                            179778.272419 secs
   .   .  *C0                       179778.272494 secs C0 => migration/2:26
   .   .  *.                        179778.272503 secs
   .   .   .  *D0                   179778.272576 secs D0 => migration/3:31
   .   .   .  *.                    179778.272585 secs
   .   .   .   .  *E0               179778.272659 secs E0 => migration/4:36
   .   .   .   .  *.                179778.272670 secs
   .   .   .   .   .  *F0           179778.272714 secs F0 => migration/5:41
   .   .   .   .   .  *.            179778.272733 secs
   .   .   .   .   .   .  *G0       179778.272815 secs G0 => migration/6:46
   .   .   .   .   .   .  *.        179778.272821 secs
   .   .   .   .   .   .  *H0       179778.272948 secs H0 => perf-exec:1315372
………

这里,每一列都是一个CPU核心,每一行都是一个事件。man perf-sched可以比我更详细地解释这些。perf schedule latency进行记录并告诉您调度中每个任务的执行经历了多少延迟。

$ sudo perf sched latency | grep busyloop
  busyloop:1315372      |  26548.094 ms |      677 | avg:   0.055 ms | max:   0.660 ms | max start: 179800.883053 s | max end: 179800.883713 s

很简约!

相关内容