web-dev-qa-db-ja.com

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:
TLDR;/proc/uptimeにはバグがあります。代わりに、/ proc/statを使用してください。

2
Kyle Brandt

(稼働時間-(idle_time/num_core))

システムがビジー状態になっている時間を秒単位で知ることができます。それを100倍するとセンチ秒になります-それはあなたの意図ですか?

IMOは、合計で何プロセッサ秒が使用可能であるかを検討し、そこからアイドル時間を差し引く方が理にかなっています。

uptime * num_core - idle_time = total active processor seconds

使用率メト​​リックは次のようになります。

active seconds / (uptime * num_core)

たとえば、システムが4コアで10秒間稼働し、5秒間のidle_timeが発生した場合:

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

87.5%の使用率。

または:

(10 - 5 / 4) / 10 = 0.875

同じことで、操作を保存します。


CPU使用率をカウンターとして取得するためのより良い方法はありますか?

これは、システム診断C++ライブラリで、すべてのコアの合計である/proc/statの最初の行を解析することによって行いました。最初の3つのフィールドは、ユーザー時間、優先度の低い(別名ニース)時間、およびシステム時間です。これらの合計がアクティブ時間の量です(ここでの単位は秒ではないことに注意してください。/proc/statの下のman procを参照してください)。

これを5秒間にわたってポーリングする場合、USER_HZを100と想定します。ここで、total_aは最初のサンプル(user + Nice + sys)であり、total_bは2番目のサンプルです。

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

これに100を掛けると、5秒間隔の平均を示すパーセンテージが得られます。

ロジックは次のとおりです。

  • total_b - total_a =サンプル間のアクティブ時間

  • サンプルの継続時間で割った5秒。

  • 測定の1秒あたりの単位で割った値(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を実行します。

シェルツールを使用してこれの正確な期間を取得するのは難しいため、合計アクティブ時間の測定値を増やし続けるか(それがあなたの意図だと思います)、かなり長い間隔を使用することができます。 30秒以上。

4
goldilocks

問題は、2つの別々のプロセスから/proc/cputimeを読み取っていることが原因である可能性があります。アイドル時間は各catの間でわずかに増加し、2回目の読み取り値が低くなる可能性があります。代わりにこれを行うことをお勧めします:

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
0
Graeme