关于linux:perf:如何检查在特定cpu上运行的进程

 2021-04-09 

perf : How to check processess running on particular cpu

在perf中是否可以选择查看在特定cpu / core上运行的进程,以及每个进程占用了该内核多少百分比。

参考链接会很有帮助。


perf用于进行性能分析,不适合您的情况。您可以尝试对/proc/sched_debug进行采样(如果它是在内核中编译的)。例如,您可以检查哪个进程当前正在CPU上运行:

1
2
3
4
5
egrep '^R|cpu#' /proc/sched_debug
cpu#0, 917.276 MHz
R          egrep  2614     37730.177313 ...
cpu#1, 917.276 MHz
R           bash  2023    218715.010833 ...

通过使用其PID作为键,您可以检查它消耗了多少CPU时间(以毫秒为单位):

1
2
grep se.sum_exec_runtime /proc/2023/sched
se.sum_exec_runtime                          :        279346.058986

但是,正如@BrenoLeit?o所述,SystemTap对您的脚本非常有用。这是您的任务的脚本。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
global cputimes;
global cmdline;
global oncpu;

global NS_PER_SEC = 1000000000;

probe scheduler.cpu_on {
    oncpu[pid()] = local_clock_ns();
}

probe scheduler.cpu_off {
    if(oncpu[pid()] == 0)
        next;

    cmdline[pid()] = cmdline_str();
    cputimes[pid(), cpu()] <<< local_clock_ns() - oncpu[pid()];

    delete oncpu[pid()];
}

probe timer.s(1) {
    printf("%6s %3s %6s %s\
","PID","CPU","PCT","CMDLINE");
    foreach([pid+, cpu] in cputimes) {
        cpupct = @sum(cputimes[pid, cpu]) * 10000 / NS_PER_SEC;

        printf("%6d %3d %3d.%02d %s\
", pid, cpu,
            cpupct / 100, cpupct % 100, cmdline[pid]);
    }

    delete cputimes;
}

它跟踪进程在CPU上运行的时刻,并通过附加到scheduler.cpu_onscheduler.cpu_off探针来停止该进程的执行(由于迁移或hibernate)。第二个探针计算这些事件之间的时间差,并将其与流程命令行参数一起保存到cputimes聚合中。

timer.s(1)每秒触发一次-它遍历聚合并计算百分比。这是Centos 7的示例输出,其中bash运行无限循环:

1
2
3
4
5
6
7
     0   0 100.16
    30   1   0.00
    51   0   0.00
   380   0   0.02 /usr/bin/python -Es /usr/sbin/tuned -l -P
  2016   0   0.08 sshd: root@pts/0""""""""
  2023   1 100.11 -bash
  2630   0   0.04 /usr/libexec/systemtap/stapio -R stap_3020c9e7ba76838179be68cd2390a10c_2630 -F3

我知道perf不是正确的方法,尽管您可以限制每个CPU的perf,例如使用perf record -C <cpulist>或什至perf stat -c <cpulist>

您将要看到的关闭事件是context-switch事件,但这根本不会为您提供应用程序名称。

我认为您需要更强大的功能,例如systemtap。