每个命令的累积 CPU 时间统计信息

每个命令的累积 CPU 时间统计信息

我使用电池运行系统,因此我非常关心累积的 CPU 时间使用情况。

与频繁运行和退出的进程相比,长时间运行的进程会在 top 中积累大量 CPU 时间,因此 top 的 TIME+ 列对我来说没有多大帮助。

我想记录一个命令的所有进程在很长一段时间内的CPU时间,然后将其全部加起来并连续显示。我会对系统上实际运行的每个命令执行此操作。例如:

bash            5:00:00
dbus-daemon     4:30:00
firefox          3:00:00
NetworkManager  1:20:00

它被排列成一个命令每行——不是一个过程每行。将命令的所有进程的 CPU 时间加在一起即可生成右侧的列。

如果只计算单个进程的 CPU 时间,bash 永远不会像我设置的那么高,但是当所有进程加在一起后,它可能会那么高。 Bash 运行了很多次,每次都有带有#!/bin/bashshebang 的 shell 脚本。

答案1

可以通过以下方式轻松获得对此的良好看法atop带有该选项的命令-p,该选项显示每个命令(即所有调用)的累积 CPU(或更确切地说资源)ssh

它以类似于正常的某些间隔显示信息top,但间隔较高(默认为 10 秒),这应该很适合该问题。例如,运行atop -p 60会给出一整分钟的摘要,这在大多数情况下应该没问题。

答案2

我的直觉是,你会从中学到powertop比实际计算过程时间更多的东西,但无论如何:

安装bpftrace;它附带execsnoop.bt示例(可能安装到 /usr/share/bpftrace/tools 中)。添加另一个探针tracepoint:syscalls:sys_enter_exit*,保存每个PID的启动时间并在退出时打印差异;类似的东西(这还没有经过测试,目前不在我最喜欢的机器上,只是努力说明):

#!/usr/bin/bpftrace
tracepoint:syscalls:sys_enter_exec*
{
    @start[pid] = nsecs;
    printf("START;%-6d;", pid);
    join(args->argv);
}
tracepoint:syscalls:sys_enter_exit*
{
    $from = @start[pid];
    $until = nsecs;
    printf("STOP;%-5d;%-16d\n", pid, $until-$from);
}

使该可执行文件,以 root 身份运行,并将输出保存到文件³。

分析输出可能会有点烦人,因为bpftrace(据我所知)没有很好的功能来避免打印程序名称和参数中的换行之类的事情。但本质上,您首先要解析START;or的一行STOP;,然后是 PID。该行结束于下一行实际以START;或开头的位置STOP;,因为join(argv)可以并且将会包含换行符。

有了它,您可以累积每个可执行文件的运行时间。

我使用电池运行系统,因此我非常关心累积的 CPU 时间使用情况。

这可能比您想象的要少——800 MHz 的 CPU 时间比 1600 MHz 的相同 CPU 时间消耗的电池更少;给定问题是否需要 800 MHz 下一半、更多或更少的时间取决于问题本身。

更糟糕的是:一个为花费很少的 CPU 时间而优化的程序会经常做类似让出之类的事情,但只有在依赖操作系统很快唤醒它之后。在低负载情况下,这很好,它允许 CPU 核心在两者之间进入睡眠状态,在高负载情况下,这很糟糕,因为突然间你们都要处理大量不必要的上下文切换,那些能让你的CPU在相同的时钟频率下执行相同的任务花费更少的能量的东西被抛弃了。

而且:特别是在嵌入式用例中,处理中断和执行其他内核工作所花费的时间与功耗相对相关,而这是您根本没有观察到的。

不过我喜欢你的例子很多

如果只计算单个进程的 CPU 时间,bash 永远不会像我设置的那么高,但是当所有进程加在一起后,它可能会那么高。 Bash 运行了很多次,每次都有一个带有 #!/bin/bash shebang 的 shell 脚本。

嗯,但是 bash 也几乎不花费 CPU 时间。它会进行一点点解析,然后调用其他一些进程并等待它完成。除非您编写的 shell 脚本非常低效,否则它会等待输入或等待命令完成,直到舍入错误为止。因此,shell 脚本实际执行所需的所有时间都花在了bash.


⁰ 设置计时器、poll/select经常更改的 fd、启动小型网络传输……

1 大多数较低的缓存都处于热状态,即实际上没有发生内存获取,并且分支预测在大多数情况下都是正确的,因此推测执行可以减少到最可能的情况

² 例如,尝试在 bash 中用长循环解决一个大型数学问题

³ 例如,chmod script.bt; sudo ./script.bt > lifetimes.log

相关内容