2019年04月21日

Raspberry Pi 3で温度やCPU周波数やCPU利用率を調べたい。直近1秒間のCPU利用率を調べたい

先週Raspberry Pi 3 model B+の状態を調べる上で、温度やCPU利用率などを調べたくなりました。
201904_rspi3bkoware.jpg

CPU利用率は、cat /proc/stat で得られます。

$ cat /proc/stat
cpu  837692 8590 52993 84258004 59104 0 3969 0 0 0
cpu0 72082 968 15608 21002872 37724 0 3709 0 0 0
cpu1 222974 2858 12102 21116091 9755 0 126 0 0 0
cpu2 329289 2844 13020 21013968 4001 0 55 0 0 0
cpu3 213347 1920 12263 21125071 7623 0 79 0 0 0
intr 14183692 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 146857 1940 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 341 28812 0 0 0 0 0 0 0 0 0 0 6178183 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 22289 7142 0 0 0 0 4853 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5482593 0 0 0 1
ctxt 10442565
btime 1554948860
processes 92930
procs_running 1
procs_blocked 0
softirq 16377931 2247219 4231156 274345 1059376 0 0 2915233 3634355 0 2016247

cpuの行が、4つのコアの状態をまとめたもの。
cpu0〜cpu3の行が、それぞれのコアの状態を示したもの。

各行は、左からcpu_user, cpu_nice, cpu_sys, cpu_idleを示しております。
user, nice, sysの合計が、いわゆるCPUを使用している時間で、idleは空き時間(アイドル時間)となります。

なので、CPU利用率を知りたければ、user, nice, sysの3値の合計を、user, nice, sys, idleの4値の合計で割ってやればよいことになります。

と、多くのサイトにはそのように書いてあって、その情報を基に実装しているシェルスクリプトを掲載しているものがありました。
が、それって、いつからいつまでのCPU利用率なんでしょうか?
CPU利用率を知りたいときは、例えば、直近1秒間とか、直近1分間とか、ある程度時間を区切って取得したいと考えますが、これはどのタイミングなのでしょうか?

おそらく、Raspberry Piが起動してからずっとなのではないか?と。
となると、この値を直接使うのは、ちょっと違う気がします。

cat /proc/stat したあと、1秒くらいスリープして、その後再び cat /proc/stat してやり、得られた値を引き算した結果を利用するのが良いのではないかと思います。
(この1秒のスリープの間には、バックグラウンドとか、別プロセスとかで、プログラムの実行が行われていると仮定しています)

というわけで、こんな感じのシェルスクリプトでも組んでおけば、気軽に調べられるかな、と思いました。

echo ■温度:
vcgencmd measure_temp

echo ■CPU周波数:
cpufreq=`vcgencmd measure_clock arm | cut -d '=' -f 2`
echo $((cpufreq/1000000))MHz

echo ■CPU利用率:

function cpuuse() {
    cpu_user=$2
    cpu_nice=$3
    cpu_sys=$4
    cpu_idle=$5
    cpub_busy=$((cpu_user+cpu_nice+cpu_sys))
    cpub_all=$((cpub_busy+cpu_idle))

    cpu_user=${13}
    cpu_nice=${14}
    cpu_sys=${15}
    cpu_idle=${16}
    cpua_busy=$((cpu_user+cpu_nice+cpu_sys))
    cpua_all=$((cpua_busy+cpu_idle))

    cpu_use=$(((cpua_busy-cpub_busy)*100/(cpua_all-cpub_all)))
   
    return $cpu_use
}

procstatcpu=`cat /proc/stat | grep 'cpu'`
cpuab=`echo "$procstatcpu" | grep 'cpu '`
cpu0b=`echo "$procstatcpu" | grep 'cpu0'`
cpu1b=`echo "$procstatcpu" | grep 'cpu1'`
cpu2b=`echo "$procstatcpu" | grep 'cpu2'`
cpu3b=`echo "$procstatcpu" | grep 'cpu3'`
sleep 1
procstatcpu=`cat /proc/stat | grep 'cpu'`
cpuaa=`echo "$procstatcpu" | grep 'cpu '`
cpu0a=`echo "$procstatcpu" | grep 'cpu0'`
cpu1a=`echo "$procstatcpu" | grep 'cpu1'`
cpu2a=`echo "$procstatcpu" | grep 'cpu2'`
cpu3a=`echo "$procstatcpu" | grep 'cpu3'`

cpuuse $cpuab $cpuaa
cpu_usea=$?
cpuuse $cpu0b $cpu0a
cpu_use0=$?
cpuuse $cpu1b $cpu1a
cpu_use1=$?
cpuuse $cpu2b $cpu2a
cpu_use2=$?
cpuuse $cpu3b $cpu3a
cpu_use3=$?

echo $cpu_usea% [ $cpu_use0% $cpu_use1% $cpu_use2% $cpu_use3% ]

シェルスクリプトで書かずにPythonで書けば、もうちょっとシンプルな書き方ができるかもしれませんが、まぁそれは後で考えることとして。

このシェルスクリプトを実行すると、次のような結果が得られます。

■温度:
temp=56.4'C
■CPU周波数:
600MHz
■CPU利用率:
2% [ 1% 4% 2% 1% ]                                                    


裏で別のターミナルを開き、yesコマンドを流し続けていると、CPU利用率が上昇することが分かります。


■温度:
temp=56.4'C
■CPU周波数:
600MHz
■CPU利用率:
6% [ 6% 10% 6% 2% ]                                                  


この他、ffmpegを流すと、CPU利用率が特定のコアでもっと上昇したり、CPU周波数が600MHzから1400MHzに上昇したりする様子を観察できます。
(Raspberry Pi 3 model Bの場合は、1200MHzに上昇します)

■温度:
temp=40.8'C
■CPU周波数:
1400MHz
■CPU利用率:
4% [ 17% 0% 0% 1% ]                                                  


(温度が下がっているのは、重い処理をさせるときにサーキュレータを回しているため)

続きを読む
posted by ayacy at 00:00 | Comment(0) | TrackBack(0) | PC