INASOFT 管理人のひとこと


フリーソフトダウンロードサイト「INASOFT」の管理人 矢吹拓也 が日々の「ひとこと」を語るページです。
2021年1月1日より、旧ブログ(blog.inasoft.org)からお引越ししました。
・INASOFT Webサイト: https://www.inasoft.org/
・管理人のふたこと(長文記事/寄稿文): https://www.inasoft.org/talk/
本業の方のお仕事が再び忙しくなりつつあるので、断続的にしばらく更新が止まることがあります。

目次 | ←前へ / 2019-04-21 00:00 / 次へ→ / 最新へ⇒

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

2019/ 4/21 0:00:00


RSSRSS配信中

https://www.inasoft.org/








先週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% ]                                                  



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



ところで、この部分について。


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'`


最初、うまくいかなくて悩んだ部分でした。

echo "$procstatcpu"のように、環境変数をダブルクォーテーションで囲っているのは、この環境変数の中身が複数行にわたるためです。ダブルクォーテーションで囲まないと、改行が無かったことになってしまい、すべて一行で処理されてしまい、うまく動かなくなります。

というか、最初は、環境変数をダブルクォーテーションで囲むというテクニックを知らなかったため、うまく動かず、悩んでしまっておりました。



目次 | ←前へ / 2019-04-21 00:00 / 次へ→ / 最新へ⇒


目次の表示:


ブログではないので、コメント機能とトラックバック機能は提供していません。ご質問・ご意見等はメールフィードバックまたはTwitter等からお願いします。いただいたご質問・ご意見などは、この「管理人のひとこと」の記事に追加、あるいは新規の記事にする形で一部または全文をそのまま、あるいは加工させていただいた上で、ご紹介させていただく場合があります。
当サイトでは掲載内容による不具合等に関する責任を持ちません。また、内容の正確性についての保証もありませんので、情報をご利用の際は、利用者の自己責任で確認をお願いします。本ページは公開から1年半後の任意のタイミングで削除される予定です。




2557271 (+0082)[+0622]

Copyright© 2010-2021 INASOFT