Raspberry Pi3 CPUクロック周波数を固定にする方法

Raspberry Pi CPU周波数の制御

2017年12月、Raspberry Pi3でCPUクロック周波数を固定に設定しました。
Raspberry Pi3のデフォルト設定では、CPU負荷やCPU温度によりCPUクロック周波数が動的に変化します。

Raspberry Pi3

Raspberry Pi3

ブログ「Raspberry Pi CPU周波数、CPU温度、CPU使用率の取得Pythonスクリプト」で、デフォルト設定の動作を確認しました。顔検出を開始するとCPU負荷が上がりCPU周波数は 600MHz → 1200MHz に上昇し、CPU温度が80度を超えるとCPU周波数を適切に低減します。

Raspberry Pi CPU周波数、CPU温度、CPU使用率の取得Pythonスクリプト

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
CPUfreq インターフェース

CPUfreq インターフェース

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 サンプル画像を表示して、そのモニター画像をカメラで撮影して顔を検出します。

顔検出とCPU周波数・温度

顔検出とCPU周波数・温度

performanceポリシー

governor動作ポリシーをperformanceに設定して確認します。

顔検出実行前のアイドル状態からCPU周波数は1200MHzになっています。顔検出を開始します。CPU周波数は1200MHzで動作しています。しかし、CPU温度が80度を超えるとCPU周波数は1162MHz程度に下がりました。

performance ポリシー動作

performance ポリシー動作

performance ポリシー動作(高温時)

performance ポリシー動作(高温時)

 

powersaveポリシー

governor動作ポリシーをpowersaveに設定して確認します。

顔検出実行前のアイドル状態からCPU周波数は600MHzになっています。顔検出を開始します。CPU周波数は600MHzで動作しています。

powersave ポリシーの動作

powersave ポリシーの動作

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

もう少し、調査が必要です。