Raspberry Pi CPU周波数の制御
2017年12月、Raspberry Pi3でCPUクロック周波数を固定に設定しました。
Raspberry Pi3のデフォルト設定では、CPU負荷やCPU温度によりCPUクロック周波数が動的に変化します。
ブログ「Raspberry Pi CPU周波数、CPU温度、CPU使用率の取得Pythonスクリプト」で、デフォルト設定の動作を確認しました。顔検出を開始するとCPU負荷が上がりCPU周波数は 600MHz → 1200MHz に上昇し、CPU温度が80度を超えるとCPU周波数を適切に低減します。
Raspberry Pi でリアルタイムなシステムを構築した場合などに、CPUクロックが動的に変化して応答速度が変化することを避けなければなりません。また、アルゴリズムの最適化実装するときに、CPUクロックが動的に変化すると実装工夫の効果を正確に評価することができません。
そこで、CPUクロック周波数を固定にする方法を調べました。
CPUクロック周波数は、CPUfreq ツールのgovernor動作ポリシー設定により変化します。
Governor | 動作 |
---|---|
performance | 負荷に関わらず最大動作周波数で動作 |
powersave | 負荷に関わらず最小動作周波数で動作 |
ondemand | CPU負荷に応じ動的に動作周波数を変更(低遅延で負荷の変化に追従) |
conservative | CPU負荷に応じ動的に動作周波数を変更(ゆっくりと段階的に変更) |
userspace | ユーザー指定の動作周波数で動作 |
schedutil | スケジューラによってCPU周波数を選択 |
cpufrequtils とは
「cpufrequtils」は、Linux Kernelが提供するCPUfreqの情報取得や操作を行うコマンドです。
cpufrequtils パッケージをインストールします
$ sudo apt-get install cpufrequtils
cpufreq インターフェースは、/sys/devices/system/cpu/cpu*/cpufreq/ のsysfs設定情報です。
Raspberry Pi3は、4つのCPUコアがありますので cpu0 から cpu3 の4種類が表示されます。
$ ls /sys/devices/system/cpu/cpu*/cpufreq/ /sys/devices/system/cpu/cpu0/cpufreq/: affected_cpus related_cpus scaling_governor cpuinfo_cur_freq scaling_available_frequencies scaling_max_freq cpuinfo_max_freq scaling_available_governors scaling_min_freq cpuinfo_min_freq scaling_cur_freq scaling_setspeed cpuinfo_transition_latency scaling_driver stats /sys/devices/system/cpu/cpu1/cpufreq/: affected_cpus related_cpus scaling_governor cpuinfo_cur_freq scaling_available_frequencies scaling_max_freq cpuinfo_max_freq scaling_available_governors scaling_min_freq cpuinfo_min_freq scaling_cur_freq scaling_setspeed cpuinfo_transition_latency scaling_driver stats /sys/devices/system/cpu/cpu2/cpufreq/: affected_cpus related_cpus scaling_governor cpuinfo_cur_freq scaling_available_frequencies scaling_max_freq cpuinfo_max_freq scaling_available_governors scaling_min_freq cpuinfo_min_freq scaling_cur_freq scaling_setspeed cpuinfo_transition_latency scaling_driver stats /sys/devices/system/cpu/cpu3/cpufreq/: affected_cpus related_cpus scaling_governor cpuinfo_cur_freq scaling_available_frequencies scaling_max_freq cpuinfo_max_freq scaling_available_governors scaling_min_freq cpuinfo_min_freq scaling_cur_freq scaling_setspeed cpuinfo_transition_latency scaling_driver stats
scaling_governor は、現在設定しているgovernor動作ポリシーを表します。
確認してみます。cat コマンドではファイル名を表示することができないので、grep コマンドを使用します。
$ grep "" /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor:ondemand /sys/devices/system/cpu/cpu1/cpufreq/scaling_governor:ondemand /sys/devices/system/cpu/cpu2/cpufreq/scaling_governor:ondemand /sys/devices/system/cpu/cpu3/cpufreq/scaling_governor:ondemand
scaling_governor は、ondemand になってるのでCPU負荷に応じ動的に動作周波数が変化します。
4つのCPUコア別にgovernor動作ポリシーの設定領域があるので、CPUコア別に設定できるのかと思いました。しかし、実際にはリンクでひとつの領域を示しているので、CPUコア別に設定できるわけではありません。
$ ls -l /sys/devices/system/cpu/cpu*/cpufreq lrwxrwxrwx 1 root root 0 12月 11 09:41 /sys/devices/system/cpu/cpu0/cpufreq -> ../cpufreq/policy0 lrwxrwxrwx 1 root root 0 12月 11 09:40 /sys/devices/system/cpu/cpu1/cpufreq -> ../cpufreq/policy0 lrwxrwxrwx 1 root root 0 12月 11 16:53 /sys/devices/system/cpu/cpu2/cpufreq -> ../cpufreq/policy0 lrwxrwxrwx 1 root root 0 12月 11 16:53 /sys/devices/system/cpu/cpu3/cpufreq -> ../cpufreq/policy0
cpufrequtils コマンド
cpufrequtils は、CPUfreqの状態を参照する cpufreq-infoコマンド と 設定する cpufreq-setコマンドがあります。
オプション指定なしでcpufreq-infoコマンドを実行するとすべての情報を参照できます。
$ cpufreq-info cpufrequtils 008: cpufreq-info (C) Dominik Brodowski 2004-2009 Report errors and bugs to cpufreq@vger.kernel.org, please. analyzing CPU 0: driver: BCM2835 CPUFreq CPUs which run at the same hardware frequency: 0 1 2 3 CPUs which need to have their frequency coordinated by software: 0 1 2 3 maximum transition latency: 355 us. hardware limits: 600 MHz - 1.20 GHz available frequency steps: 600 MHz, 1.20 GHz available cpufreq governors: conservative, ondemand, userspace, powersave, performance, schedutil current policy: frequency should be within 600 MHz and 1.20 GHz. The governor "ondemand" may decide which speed to use within this range. current CPU frequency is 600 MHz. cpufreq stats: 600 MHz:92.62%, 1.20 GHz:7.38% (28) analyzing CPU 1: // 同上なので省略します analyzing CPU 2: // 同上なので省略します analyzing CPU 3: // 同上なので省略します
–help オプションでコマンドオプションを調べます。
$ cpufreq-info --help cpufrequtils 008: cpufreq-info (C) Dominik Brodowski 2004-2009 Report errors and bugs to cpufreq@vger.kernel.org, please. Usage: cpufreq-info [options] Options: -c CPU, --cpu CPU CPU number which information shall be determined about -e, --debug Prints out debug information -f, --freq Get frequency the CPU currently runs at, according to the cpufreq core * -w, --hwfreq Get frequency the CPU currently runs at, by reading it from hardware (only available to root) * -l, --hwlimits Determine the minimum and maximum CPU frequency allowed * -d, --driver Determines the used cpufreq kernel driver * -p, --policy Gets the currently used cpufreq policy * -g, --governors Determines available cpufreq governors * -r, --related-cpus Determines which CPUs run at the same hardware frequency * -a, --affected-cpus Determines which CPUs need to have their frequency coordinated by software * -s, --stats Shows cpufreq statistics if available -y, --latency Determines the maximum latency on CPU frequency changes * -o, --proc Prints out information like provided by the /proc/cpufreq interface in 2.4. and early 2.6. kernels -m, --human human-readable output for the -f, -w, -s and -y parameters -h, --help Prints out this screen
$ cpufreq-set --help cpufrequtils 008: cpufreq-set (C) Dominik Brodowski 2004-2009 Report errors and bugs to cpufreq@vger.kernel.org, please. Usage: cpufreq-set [options] Options: -c CPU, --cpu CPU number of CPU where cpufreq settings shall be modified -d FREQ, --min FREQ new minimum CPU frequency the governor may select -u FREQ, --max FREQ new maximum CPU frequency the governor may select -g GOV, --governor GOV new cpufreq governor -f FREQ, --freq FREQ specific frequency to be set. Requires userspace governor to be available and loaded -r, --related Switches all hardware-related CPUs -h, --help Prints out this screen
ondemandポリシー
cpufreq-infoコマンド(-p と -f)で、governor動作ポリシーと動作周波数を参照します。
$ cpufreq-info -p 600000 1200000 ondemand $ cpufreq-info -f 600000
デフォルトの設定は、ondemandポリシーです。過負荷が無い状態ですので600MHzで動作しています。
performanceポリシー
cpufreq-setコマンドで、governor動作ポリシーをperformanceに設定します。root権限が必要ですので、sudoでコマンドを起動します。
$ sudo cpufreq-set -g performance
cpufreq-infoコマンドで、governor動作ポリシーと動作周波数を参照します。
$ cpufreq-info -p 600000 1200000 performance $ cpufreq-info -f 1200000
performanceポリシーとなり、1200MHzで動作しています。
powersaveポリシー
cpufreq-setコマンドで、governor動作ポリシーをpowersaveに設定します。root権限が必要ですので、sudoでコマンドを起動します。
$ sudo cpufreq-set -g powersave
cpufreq-infoコマンドで、governor動作ポリシーと動作周波数を参照します。
$ cpufreq-info -p 600000 1200000 powersave $ cpufreq-info -f 600000
powersaveポリシーとなり、600MHzで動作しています。
Python版OpenCVによる顔検出
governor動作ポリシーを変更して、顔検出を実行しながら CPU周波数/CPU温度/CPU使用率をモニターしてみます。画面にOpenCVのlena.jpg サンプル画像を表示して、そのモニター画像をカメラで撮影して顔を検出します。
performanceポリシー
governor動作ポリシーをperformanceに設定して確認します。
顔検出実行前のアイドル状態からCPU周波数は1200MHzになっています。顔検出を開始します。CPU周波数は1200MHzで動作しています。しかし、CPU温度が80度を超えるとCPU周波数は1162MHz程度に下がりました。
powersaveポリシー
governor動作ポリシーをpowersaveに設定して確認します。
顔検出実行前のアイドル状態からCPU周波数は600MHzになっています。顔検出を開始します。CPU周波数は600MHzで動作しています。
usersaveポリシー
governor動作ポリシーをusersaveに設定して確認します。
ユーザーの設定したCPU周波数で動作すると思ったのですが、最高周波数の1200MHzで動作し任意のCPU周波数で動作しませんでした。
$ sudo cpufreq-set -g userspace $ sudo cpufreq-set -f 800MHz $ cpufreq-info -p 800000 1200000 userspace $ cpufreq-info -f 1200000
もう少し、調査が必要です。