Raspberry Pi 3、4のSoCでは、4つのCPUコアを搭載しています。シングルコアのCPUではマルチスレッドで複数の処理を実行したい場合は、処理を複数のスレッドに分けて、順番を切り替えて実行する必要があります。
しかし、マルチコアのraspberry Piでは処理を切り替えて実行するのではなく、処理を各コアに割り当て、ハード的に同時実行することが可能です。
今回はRaspberry Piで行うマルチコア並列処理について解説していきます。
Raspberry Pi(ラズベリーパイ)とは
Raspberry Pi 5は、Raspberry Pi財団が開発した最新のシングルボードコンピュータで、従来モデルよりも大幅な性能向上を実現しています。
搭載される64ビットクアッドコアプロセッサは、クロック速度が最大2.4GHzに達し、前世代よりも処理速度が格段に向上しました。また、4GBまたは8GBのRAMを選択できるため、教育用途からリソースを必要とするプロジェクトまで幅広く対応可能です。
グラフィックス性能も強化され、4K解像度でのデュアルディスプレイ出力をサポートしています。さらに、新たにPCIeインターフェイスが追加され、外部ストレージや高速デバイスとの接続が容易になりました。Wi-Fi 6やBluetooth 5.2の導入により、無線通信も高速かつ安定。
教育、IoT、AI開発、メディア再生など、多様な用途に対応するRaspberry Pi 5は、初心者から上級者まで幅広いユーザーにとって魅力的な選択肢となっています。
Raspberry Piでできることについては以下の記事で解説していますので、あわせてご覧ください。
やりたいこと
現在、製作しているPaspberry Piベースのスパイダーロボット、PiCrawlerでは、これまでロボットを動かすためのサーボモーター制御やディープラーニングを使った物体検出などの機能を実装してきました。
これらの機能はこれまで単体で動かしていたので、特に気にすることなくPythonでやりたいことをプログラムで順に記述していくだけで実現できました。
しかし、最終的に一つのアプリケーションに統合し、複数の機能を同時に使用したい場合は、一つのプロセッサー上で複数のアプリケーションがうまく動作するように、プログラムの書き方を考えなければいけません。
Raspberry Piは4コアの高性能SoCを搭載しています。このSoCの性能を使って複数のコアで並列実行することで高速にアプリケーションを動作させる方法を調べてみました。
動作環境
今回のシステムの動作環境は以下の通りです。
ハードウェア:Raspberry Pi 3 ModelB
OS:Raspbian 10.11
Python:3.7.3
Pythonでマルチコア並列処理を実装する方法
今回はプログラムを機能ごとに別け、プロセスとして実行する方法を試してみたいと思います。この場合、各プロセスはそれぞれ独立したメモリ空間を使用して動作します。このようなアプリケーションの実装方法をマルチプロセスと言います。
Pythonでマルチプロセスを実装するためには、multiprocessingというライブラリを使用します。multiprocessingはPythonの標準ライブラリとなりますので、インストールなどをせずに使用することができます。
作成したソースコード
実際に作成したソースコードは以下の通りです。
cal1、cal2、cal3という異なる計算を行うメソッドを用意し、それぞれを独立したプロセスとして並列実行した結果を見てみたいと思います。
import multiprocessing as mp
#加算を100万回実行
def cal1(q):
for cal in range(1000000):
cal += 1
q.put(cal)
#加算を50回実行
def cal2(q):
for cal in range(50):
cal += 1
q.put(cal)
#加算を1000回実行
def cal3(q):
for cal in range(1000):
cal += 1
q.put(cal)
if __name__ == '__main__':
#プロセス間通信用のキューを生成
queue = mp.Queue()
#プロセスを生成
p1 = mp.Process(target=cal1, args=(queue,))
p2 = mp.Process(target=cal2, args=(queue,))
p3 = mp.Process(target=cal3, args=(queue,))
#プロセス実行
p1.start()
p2.start()
p3.start()
#キューから結果を取り出す
print(queue.get())
print(queue.get())
print(queue.get())
4行目:
加算を100万回実行するメソッドです。
10行目:
加算を50回実行するメソッドです。
16行目:
加算を1000回実行するメソッドです。
24行目:
プロセス間でデータをやり取りするために使用するキューを生成します。
27~29行目:
各メソッドを独立したプロセスとして生成します。
32~34行目:
各プロセスを実行します。
37~39行目:
計算結果を表示します。
実行結果
実行結果は以下の通りです。計算が早く終わった順に結果がキューにセットされ、読みだされているのがわかると思います。
50
1000
1000000
通常であればPythonのコードは逐次処理で実行されますので、cal1の100万回の加算処理が完了するまでcal2の計算処理が実行できません。
しかし今回は各計算をCPUの別々のコアに分散して並列実行しているため、一番計算量が少ないcal2の計算が先に完了し、計算結果が先に通信用のキューにセットされています。
そして、一番最初に実行されたcal1の処理は、計算回数が一番多いため、最後に完了してキューに結果がセットされていることがわかるかと思います。
このように複数のメソッドを同時実行できることが確認できました。
\ Pythonを自宅で好きな時に学べる! /
マルチプロセスの応用
multiprocessingでプロセス間でのデータの受け渡し方法については、以下の記事で解説しています。
multiprocessingで実際にロボットを制御する方法については、以下の記事で解説しています。
まとめ
今回のようなマルチコアを使った並列分散処理の実装を行うと、ディープラーニングを使った物体検出と、モーター制御などを同時に行うことができるようになります。
今後は実際にロボットのアプリケーションで使用する際のプロセス間通信の方法なども作りこんでいきたいと思います。
また、以下の記事で効率的にPythonのプログラミングスキルを学べるプログラミングスクールの選び方について解説しています。最近ではほとんどのスクールがオンラインで授業を受けられるようになり、仕事をしながらでも自宅で自分のペースで学習できるようになりました。
スキルアップや副業にぜひ活用してみてください。
スクールではなく、自分でPythonを習得したい方には、いつでもどこでも学べる動画学習プラットフォームのUdemyがおすすめです。
講座単位で購入できるため、スクールに比べ非常に安価(セール時1200円程度~)に学ぶことができます。私も受講しているおすすめの講座を以下の記事でまとめていますので、ぜひ参考にしてみてください。
それでは、また次の記事でお会いしましょう。
\ Raspberry Piを使ったアプリ開発を学びたい人には自宅で学べるUdemyがおすすめ! /
講座単位で購入できます!
おすすめの記事
Pythonを習得するのにおすすめのプログラミングスクールをまとめています。
Raspberry Piで制御するロボット製作の記事をまとめています。
コメント
コメント一覧 (2件)
こんにちは。
私も今現在、raspberry pi 4を用いて、ステッピングモーター2台の制御に挑戦しています。
具体的には、threadingを用いてステッピングモーターでライントレースをしようとしているのですが、今のところ上手くいってないです笑
私もこれからmultiprocessingもやってみようと思います。お互い頑張りましょうね。
お茶漬けさん、コメントありがとうございます!
ライントレーサーはスレッドの管理が結構シビアそうですよね😄💦
multiprocessingはプロセス間通信さえしっかりできればthredingよりお手軽に使えるかなと思います。
お互い頑張りましょう!