LoginSignup
10
1

More than 3 years have passed since last update.

ElixirでIoT#4.4:Nervesの動作周波数を制御する

Last updated at Posted at 2020-12-20

どうもこんにちわ.
この記事は Seeed UG Advent Calendar 2020 の20日目の記事です.

はじめに

NervesJP というコミュニティをやっとります.
れっつじょいなす!!

NCJP_Logo3_V2.png

昨年のAdvent Calendarでは,23日目に『ElixirでIoT#4.2:BeagleBone GreenでNerves/Elixirを動かす』という記事をお届けしました.

ところでNervesってなんやねん!??という方は,:arrow_up:の記事に加えて,このあたりの情報をご参照ください.

今年のAdvent Calendarでは,レペゼンNervesJPのAdvent Calendar芸人!?な @torifukukaiou さんより,こんな記事をお届けしております.

$\huge{Nervesならできるもん!}$
って言いたいだけですのやつね〜 30回くらい笑わせてもらいました^^;

ということでこの記事では,@torifukukaiou さんを見習って,日頃よりNervesJPでお世話になっておりますSeeed K.K.さんへの感謝の恩返し!!ということで,BeagleBone Greenで遊べるヒトネタをご紹介したいと思います.

[PR] Seeed K.K.さん,太っ腹!! [広告]
※プレゼント枠は瞬殺でした,,, でもまだ見学枠でぜひ!!

【オンライン】豪華プレゼント付!Elixir/Nerves(ナーブス)体験ハンズオン!
ALGYAN

Nerves開発環境の準備方法

おぉっなんかNerves楽しそうだ!すぐに試してみたい!!という方向けに,VS Code dev-containerを使ったお手軽な開発環境を用意しています.ぜひどうぞです^^;

いやっガッツリNervesやっていくぜ!という方は,コチラをどうぞです.

動作周波数の制御??

いわゆるDVFS(Dynamic Voltage and Frequency Scaling)というやつです.
Linuxが普通に動くような最近のSoCでは,そのプロセッサの動作周波数を何段階かに変更することができます.アプリの処理が忙しいときは高い周波数で速く動いて,ヒマなときは周波数を低くしてゆっくり動かすことができます.

なにが嬉しいかというと,消費エネルギーの節約に繋がります.
動作周波数と供給電圧は比例関係にあり,電圧を下げることによって消費電力を削減することができます.周波数を低くしたらアプリの実行時間は大きくなりますが,消費エネルギー的には小さく抑えられることが多いです(正確にはもうちょいありますが,ザックリ説明ということで^^;

image.png

Linux v3.4以降では cpufreq というモジュールが標準で搭載されています.
Nervesでは(というかLinux)では,このモジュールを使ってプロセッサの周波数を変更することができます.

BeagleBone Green対応のNerves(本記事執筆時点の最新版 nerves_system_bbb v2.8.2)では,組み込みLinuxであるBuildroot v2020.08.2が動作しています.Linux kernelのバージョンは5.4です.
要するに,NervesでもDVFSできるぜっ!てことです.

cpufreqの構成

cpufreq というモジュールは /sys/devices/system/cpu/cpufreq/policy0/ にあります.Nervesの動作するBeagleBone Greenにアクセスしして,その構成を見てみましょう.

$ ssh nerves.local 
Interactive Elixir (1.11.2) - press Ctrl+C to exit (type h() ENTER for help)
Toolshed imported. Run h(Toolshed) for more info.
RingLogger is collecting log messages from Elixir and Linux. To see the
messages, either attach the current IEx session to the logger:

  RingLogger.attach

or print the next messages in the log:

  RingLogger.next

iex(1)> cpufreq_dir = "/sys/devices/system/cpu/cpufreq/policy0/" 
"/sys/devices/system/cpu/cpufreq/policy0/"
iex(2)> ls cpufreq_dir                                           
affected_cpus                     cpuinfo_cur_freq                  cpuinfo_max_freq                  
cpuinfo_min_freq                  cpuinfo_transition_latency        related_cpus                      
scaling_available_frequencies     scaling_available_governors       scaling_cur_freq                  
scaling_driver                    scaling_governor                  scaling_max_freq                  
scaling_min_freq                  scaling_setspeed                  stats                             

いろんなファイルがあるので,要点な感じだけ.

  • cpuinfo_cur_freq: 現在の動作周波数
  • cpuinfo_max_freq, _min_freq: 設定可能な最大/最小の周波数
  • scaling_available_frequencies: 設定可能な周波数の一覧
  • scaling_available_governors: 設定可能なガバナの一覧
  • scaling_max_freq, _min_freq: ガバナで調節される周波数の上限/下限値(設定値)
  • scaling_setspeed: 手動で調節する場合の周波数の設定値

設定可能な周波数

BeagleBone Greenで設定可能な周波数の一覧を見てみましょう.

iex(3)> cat(cpufreq_dir <> "scaling_available_frequencies")     
300000 600000 720000 800000 1000000 

単位はKHzです.つまり300MHzから1.0GHzまでの5段階の周波数が設定できるわけです.

設定可能なガバナ

ガバナ(governor)というのは,cpufreq で提供される標準で用意されている周波数制御のポリシーです.BeagleBone GreenのNervesではこんな感じになっています.

iex(4)> cat(cpufreq_dir <> "scaling_available_governors") 
ondemand userspace powersave conservative performance 

5種類のガバナがあります.ざっくりこんな感じです.

governor 意味
performance 常に最大の動作周波数に固定
powersave 常に最小の動作周波数に固定
userspace ユーザの指定する周波数で動作
ondemand アプリ動作負荷に応じて自動調節
conservative アプリ動作負荷に応じて,適応的に自動調節

ondemandconservative の違いは,前者はCPU使用率に応じてすぐにその対応する周波数に切り替える(例えば300MHzから一気に800MHzに変更したりする)のに対して,後者はゆっくり適応的に切り替えます(例えば300MHzから,600MHzと720MHzを経由して,それでも負荷が高ければ800MHzにする)

ちなみにデフォルト(電源リセット後)の設定は conservative です.

iex(5)> cat(cpufreq_dir <> "scaling_governor")           
conservative

設定方法

Linuxカーネルに設定を任せる場合は,scaling_governor に設定したいガバナを書き込むだけです.
最大にする performance と最小にする powersave にして,周波数を見てみましょう.

iex(6)> File.write(cpufreq_dir <> "scaling_governor", "performance")
:ok
iex(7)> cat(cpufreq_dir <> "cpuinfo_cur_freq")
1000000

iex(8)> File.write(cpufreq_dir <> "scaling_governor", "powersave")  
:ok
iex(9)> cat(cpufreq_dir <> "cpuinfo_cur_freq")                    
300000

まぁカーネルに任せといたほうが良いんですが,どうしても自分で変えたい!という場合は,ガバナを userspace に設定して, scaling_setspeedに設定可能な値を書き込みます.

iex(10)> File.write(cpufreq_dir <> "scaling_governor", "userspace")
:ok
iex(11)> File.write(cpufreq_dir <> "scaling_setspeed", "720000")   
:ok
iex(12)> cat(cpufreq_dir <> "cpuinfo_cur_freq")                      
720000

効果のほどは??

それでは周波数制御の効果を見てみましょう.

こんな感じで,フィボナッチ数を求める関数をベタに実装しました.

defmodule NervesBbg do
  @moduledoc """
  Documentation for NervesBbg.
  """

  @doc """
  Calculate Fibonacci number by recursive call.

  ## Examples

      iex> NervesBbg.fib(20)
      6765

  """
  def fib(0), do: 0
  def fib(1), do: 1
  def fib(n), do: fib(n-1) + fib(n-2)
end

周波数を下から順に切り替えて,:timer.tcで実行時間を測定してみました.

iex(13)> File.write(cpufreq_dir <> "scaling_setspeed", "300000")
:ok
iex(14)> :timer.tc(NervesBbg, :fib, [20])
{7184, 6765}
iex(15)> File.write(cpufreq_dir <> "scaling_setspeed", "600000")
:ok
iex(16)> :timer.tc(NervesBbg, :fib, [20])                       
{3570, 6765}
iex(17)> File.write(cpufreq_dir <> "scaling_setspeed", "720000") 
:ok
iex(18)> :timer.tc(NervesBbg, :fib, [20])                       
{3032, 6765}
iex(19)> File.write(cpufreq_dir <> "scaling_setspeed", "800000")
:ok
iex(20)> :timer.tc(NervesBbg, :fib, [20])                       
{2645, 6765}
iex(21)> File.write(cpufreq_dir <> "scaling_setspeed", "1000000")
:ok
iex(22)> :timer.tc(NervesBbg, :fib, [20])                        
{2127, 6765}

おぉっ,なんだか速くなっているようです.
表にするとこんな感じです.

周波数[KHz] 実行時間[us]
300000 7184
600000 3570
720000 3032
800000 2645
1000000 2127

おわりに

ということでこの記事では,Nervesで動作周波数を制御する方法を紹介しました.
ていうか実はNervesどうこうじゃなく,Linuxが"いごく"んならなんでもおけです.

それといろいろ設定できますが,ガバナは割りと賢いので,デフォルトの conservative にしとけば性能と電力のバランスは良いです.
ただし周波数が切り替わると実行時間が変動しますし,切り替え時に時間/エネルギーのオーバヘッドも掛かります.ちょっとシビアなことをしたいな??というときは,周波数の固定化など検討してもよいかもしれません.

ただし,じゃあ performance で最大にしときゃええんちゃう??となると,SoC BBQがお楽しみになれるので注意しましょう^^
image.png

ということで改めまして, NervesJP にれっつじょいなす!!

NCJP_Logo3_V2.png

10
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
1