如何获取 CPU 百分比作为计数器?

如何获取 CPU 百分比作为计数器?

我想将 CPU 总利用率作为计数器进行监控。我希望它作为计数器的原因是样本之间的数据不会丢失(并且我可以让绘图端计算速率)。

我最初的方法是使用/proc/uptime公式(uptime-(idle_time/num_core))*100。这通常在大量服务器上似乎是准确的(大约 98% 的时间),但有时我似乎得到了错误的结果。例如,以下内容似乎表明存在负 CPU 使用率,这实际上没有意义:

[root@ny-lb05 ~]# echo -e "scale=10\n ($(cut -f1 -d' ' /proc/uptime)-($(cut -f2 -d' ' /proc/uptime)/16))*100" | bc
5646895.3750000000
[root@ny-lb05 ~]# echo -e "scale=10\n ($(cut -f1 -d' ' /proc/uptime)-($(cut -f2 -d' ' /proc/uptime)/16))*100" | bc
5646891.5625000000

在此服务器上我正在运行:

Linux ny-lb05.ds.stackexchange.com 2.6.32-431.11.2.el6.x86_64 #1 SMP Tue Mar 25 19:59:55 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

有人发现这种计算方法有错误吗?有没有更好的方法来获取 CPU 利用率作为计数器?

更新:
所以我追求的是作为单调递增计数器的总使用时间。我希望总利用率永远不应该减少。但以下情况似乎就是这种情况: [root@ny-lb05 ~]# read uptime idle </proc/uptime; echo -e "scale=1000\n ($uptime*16-($idle))" | bc 903874.23 [root@ny-lb05 ~]# read uptime idle </proc/uptime; echo -e "scale=1000\n ($uptime*16-($idle))" | bc 903870.29

另外,根据 /proc/cpuinfo,cores=siblings 所以我相信 HT 没有启用。

更新2:
太长了; /proc/uptime 有 bug,请使用 /proc/stat 代替。

答案1

(正常运行时间-(idle_time/num_core))

可以了解系统忙碌了多长时间(以秒为单位)。将其乘以 100 就是厘秒——这是你的意图吗?

IMO 考虑总共有多少处理器可用秒,并从中减去空闲时间会更有意义:

uptime * num_core - idle_time = total active processor seconds

利用率指标可能是:

active seconds / (uptime * num_core)

例如,如果系统在 4 个核心上运行了 10 秒,空闲时间为 5 秒:

(10 * 4 - 5) / (10 * 4) = 0.875

利用率87.5%。

或者:

(10 - 5 / 4) / 10 = 0.875

同样的事情,节省了一个操作。


有没有更好的方法来获取 CPU 利用率作为计数器?

我在系统诊断 C++ 库中通过解析 的第一行来完成此操作/proc/stat,这是所有内核的总和。前三个字段是用户时间、低优先级(也称为良好)时间和系统时间。这些的总和就是活动时间量(注意这里的单位不是秒,见/proc/stat下文man proc)。

如果您轮询超过 5 秒,假设 USER_HZ 为 100,其中total_a是第一个样本 (user + Nice + sys),total_b是第二个样本:

(total_b - total_a) / 5 / 100 / num_cores = usage ratio

如果将其乘以 100,您将得到一个百分比,表示 5 秒间隔内的平均值。

逻辑如下:

  • total_b - total_a= 样本之间的活动时间

  • 除以样本的持续时间,即 5 秒。

  • 除以每秒测量单位 (USER_HZ)

  • 除以核心数

USER_HZ 几乎肯定是 100。要检查:

#include <stdio.h>
#include <unistd.h>

int main (void) {
    printf (
        "%ld\n", 
        sysconf(_SC_CLK_TCK)
    );

    return 0;
}

编译:gcc whatever.c,运行./a.out.

使用 shell 工具很难获得准确的持续时间,因此您可以增加总活动时间的测量值(我认为这是您的意图)或使用相当长的间隔,例如 30 秒以上。

答案2

您的问题可能是因为您正在/proc/cputime从两个单独的进程中读取数据。每次之间的空闲时间会略有增加cat,因此第二次读数可能会较低。我建议改为这样做:

read uptime idle </proc/cputime
echo -e "scale=10\n ($uptime-($idle/16))*100" | bc

另外,如果您希望结果是总利用率百分比,那么您应该再次除以正常运行时间:

read uptime idle </proc/cputime
echo -e "scale=10\n ($uptime-($idle/16))/$uptime*100" | bc

相关内容