Raspberry Piシリーズの性能を活かす (Raspbian)

Last modified: 2019-07-15

Raspberry Piは最近のPCと比べて処理性能が低いが、工夫次第で性能の低さをある程度補うことはできる。

CPUの処理を減らす

プログラミング言語の実行環境は高速なものを選択する

CPythonの代わりにPyPyを用いる

PyPyはPythonの標準ライブラリのみを用いたスクリプトを高速かつ省メモリで実行できる。Raspberry Piのアーキテクチャもサポートされているため、IntelやAMDのCPUを搭載したPC上のGNU/Linuxと同じように使うことができる。

パッケージ名は以下。

  • Python 3互換版: pypy3(Buster以降のみ)
  • Python 2互換版: pypy

PyPyはCPython用に提供される言語バインディングなどのモジュールを利用できない。動かしたいスクリプトがPyPyで動かなければCPythonで動かす必要がある。

スクリプト内で行われる処理が少なく実行時間が非常に短いスクリプトではCPythonを使ったほうが時間がかからないため、頻繁に実行するスクリプトであってもCPythonより速いかどうかをtimeコマンドなどで確かめたほうがよい。

Luaの代わりにLuaJITを用いる

JITを用いて高速に動作するLuaJIT(パッケージ名はluajit)はRaspberry Piのアーキテクチャをサポートしており、パッケージも用意されているため導入は楽。こちらはC言語によるLuaの公式な実装を対象とした言語バインディングの類をそのまま利用できる。

コンパイラオプションで最適化したプログラムを動かす

Raspbianのパッケージは初代PiやZeroの世代のCPUに最適化されており、新しい世代のPiではその世代のCPU向けに最適化するためのコンパイラオプションを付けてプログラムをビルドし直して置き換えると、それらがより高速に動作するようになる。

例えばPi 3では-march=armv8-a+crc -mfpu=neon-fp-armv8 -mtune=cortex-a53を指定する。

コンパイラの最適化オプションとしてはPGO(Profile-Guided Optimization)を用いるのも効果的で、Piの世代に関わらず使用できる。

もしくは、新しい世代(3以降)のPiを使用している場合にRaspbian以外の64bitOSを使用するとOS全体に渡ってCPU処理が高速になるが、メモリ使用量が増えてしまうかもしれない(未確認・Pi 4以降のメモリ多めのモデルなら使いやすそう)。

Webサイトのスクリーンショットを撮る場合のソース編集

“特定の時刻に特定のサイトの同じページにアクセスしてWebページ内の情報を画面に表示するのを自動化する” というような用途では、Chromiumの “ヘッドレスモード” でスクリーンショットを保存してその画像を表示するというやり方がある。このとき、ページ内のスクリーンショットに含まれない(描画されない)範囲が広いとスクリーンショットの書き出し時に無駄に時間がかかることになるため、可能であればHTMLのソースをPythonなどで編集して必要最小限の範囲に切り取ってからChromiumに渡す。

  1. HTMLファイルを取得
  2. レンダリングされない範囲のHTMLコードをなるべく除くように自動で編集したHTMLファイルを/dev/shm/以下などに保存
  3. file:///dev/shm/name.html#idnameのような形式のURLを--temp-profile --disable-javascript --disable-gpu --headless --screenshot --window-size=[画面の幅],[画面の高さ]オプション付きでChromiumに渡す
  4. mpvなどでscreenshot.pngを指定時間表示
  5. 不要になったファイルを消す

手元の環境ではこれらを全て1つのPythonスクリプトで行うようにしてcrontabの設定によって決まった時刻に情報を表示するようにしており、レンダリングされない範囲のコードの除外により処理時間が数秒単位で短縮された(Chromium自体の起動が遅いので処理時間自体はそれなりにかかる)。

GPUを活かす

動画再生支援を用いる

動画の再生はCPU処理で行うと性能的に厳しいものとなり、YouTubeのような動画サイトをWebブラウザで訪問してPCと同様に再生しようとすると、Pi 3B+の時点で1280x720辺りが限界で、CPUにも負荷がかかり続けるので発熱もひどくなる。CPUが強化されたPi 4以降ならより高品質な画質でも見られるかもしれないが、発熱はそれなりにありそう。

Raspberry Piでは、映像コーデックがH.264の動画に対する動画再生支援が同機能に対応するソフトウェアから利用可能で、1920x1080であれば全機種で30fpsのデコード(およびエンコード)をサポートし、Pi 3以降では1920x1080の60fps動画も再生できる。Pi 4以降ではH.265にも対応し、解像度も4kまでGPUが対応する。

Raspberry PiのGPUにおける動画再生支援機能はAMD, NVIDIA, IntelのGPU製品に搭載された動画再生支援機能をGNU/Linuxから利用する仕組み(VDPAUやVAAPI)には対応しておらず、Raspberry PiのGPUにおける動画再生支援に直接プレーヤのソフトウェア側が対応している必要がある。

YouTubeの場合は外部ツールで動画ファイルの実際のURLを取得してプレーヤのプログラムに渡すことができるが、他の動画サイトで動画ファイルのURLを調べるにはWebブラウザに組み込まれたWeb開発ツールまたはアドオン(拡張機能)を用いる必要があるかもしれない。

Raspberry Piの動画再生支援に対応した動画プレーヤ

  • omxplayer
    • コマンドラインのプレーヤ
    • 直接接続されているストレージなどに入っている動画ファイルの再生のみであればこれで事足りる
    • YouTubeの動画については、映像と音声が分かれていることがある関係でこのプレーヤは適していない
      • 無音になってもよいなら問題はない
  • VLC
    • 映像出力先を適切なものにする必要がある
    • GUIもあるが再生中は(他プレーヤと同様)ウィンドウの中ではなく画面全体に直接映像が表示される
  • mpv
    • コマンドラインのプレーヤ
    • YouTube動画の再生にも便利で、Pi 3以降なら60fpsの動画も滑らかに再生できる
    • Pi 3なら--ytdl-format="bestvideo[height<=?1080][vcodec!=?vp9]+bestaudio/best"(60fpsも受け付ける)、古いモデルでは30fpsまでにするために--ytdl-format="bestvideo[height<=?1080][fps<=?30][vcodec!=?vp9]+bestaudio/best"を指定する
      • ディスプレイ解像度が1920x1080より小さい場合は[height<=?1080]の部分を縦方向のピクセル数に合わせて指定する

Raspberry PiのGPUにおける動画再生支援機能を用いると実機の画面出力から動画が再生される仕様となっている。

GPUを活かした画像表示ソフトウェアを用いる

omxiv

Raspbianのパッケージはないが、コマンドラインの画像ビューアomxivはJPEG画像の内のベースライン(プログレッシブではないもの)のファイルのデコードにGPUを用い、全ての画像の描画処理にもGPUが用いられる。そのため、画像のサイズが大き過ぎなければとても快適に表示が行える。

  • 引数は画像ファイルのパス名(複数可)の他、ディレクトリでも指定可能
  • --blank(-b)オプションを付けると空白部分が黒背景になる
  • --transition blend(-T blend)オプションを付けると画像の切り替わり時にトランジション効果がかかる

mpvを用いた画像表示

mpvには画像ファイルの表示機能があり、GPUを用いて汎用的なGUI画像ビューアよりも高速に描画することができる。この場合、JPEGファイルのデコード処理を高速化したりはできないが、FFmpegのビデオフィルタの仕組みを利用してネガ反転などのエフェクトを画像にかけることができる。

表示時間は--image-display-duration=[秒数またはinf]オプションで指定でき、指定時間経過後に終了させることもできる。

(screenshot.pngをネガ反転して高速に表示し、1時間30分後に終了)
$ mpv --really-quiet --osd-level=0 --image-display-duration=$((1*3600+30*60)) --fullscreen -vf negate screenshot.png

ネガ反転は白背景のWebページのスクリーンショットを表示する際にブルーライトを抑える目的で適用している。また、Raspberry Pi向けなどにIPS方式の液晶ディスプレイを使用している場合には若干の節電にもなる。