電子趣味の部屋

電子系のガジェットやアプリ開発等の趣味の話題を書いてます

Raspberry Pi Zero 2 Wでスーパーコンピュータをつくってみた

Raspberry Pi Zero 2 Wでスーパーコンピュータをつくってみました。
とは言っても非常に非力なのは承知で、単純に遊んでみたかったのと、並列処理のプログラミングに興味があったので環境が欲しいと思ってました。

Raspberry Pi Zero 2 Wにしたのは最小のものにしたくてネタ的にも面白いと思ってたからです。
しかし現在入手が難しく、約1年かけて色々なショップをウォッチして3個入手できたので、これでクラスタ化した環境を作ってみました。

今回Raspberry Piでスーパーコンピュータを作るのにちょうど良い本を見つけたので、これを読みながら構築してみました。
Raspberry Piでスーパーコンピュータをつくろう!

今回は色々試しながらで何回もやり直したりしながらだったので構築手順は特に覚えているわけではなく、説明しにくいので詳細は書きません。興味のある方は、『Raspberry Piでスーパーコンピュータをつくろう!』を読んでみてください。

概要的には以下の手順で構築しました。

1. Raspberry Pi OSをセットアップ
それぞれIPアドレスは固定にして、ホスト名を変更します。

2. /etc/hosts を編集
お互いにホスト名でアクセスできるように/etc/hostsを編集します
今回は以下のように同じものをすべてのサーバに設定しました

192.168.0.41    rpisc01
192.168.0.42    rpisc02
192.168.0.43    rpisc03

3. 3台とも必要なものをインストール

sudo apt install build-essential manpages-dev gfortran nfs-common nfs-kernel-server openmpi-bin libopenmpi-dev openmpi-doc keychain nmap

スレーブとなる2台目以降はnfs-kernel-serverは必要ないのですが、あっても困らないので統一しました。

4. NFS設定
コンパイルした実行ファイルは全てのサーバで必要になります。
マスターサーバに適当な作業ディレクトリを作成し、スレーブからマウントして同じものが各サーバから使用できるようにします。

簡単ですが以上のように構築しました。

テストとして本に書いてあったπの値を求める計算をしてみました。
ソースコードは著作物で公開してよいかわからないのでここでは書きません。

ソースはmpiccコマンドでコンパイルします。

mpicc test1.c -o test1

これで実行ファイルとしてtest1が生成されます。

実行はmpiexecコマンドで実行できます。

例:プロセス(スレッド)を1で実行する場合

mpiexec -n 1 test1

実行時間を見るためにtimeコマンドを使用してまずコアを1個使用する状態で実行してみます。
"Enter number of segments:"と表示され入力を求められますが、本の例と同じように300000で実行してみます。

$ time mpiexec -n 1 test1

#######################################################

Master node name: rpisc01

Enter number of segments:

300000

*** Number of processes: 1

     Calculated pi = 3.14159265359071326
              M_PI = 3.14159265358979311
    Relative Error = 0.00000000000092015

real    46m38.851s
user    46m32.714s
sys     0m0.784s

処理の実時間をreal+sysとすると約46分39秒でした。

次はコアを4個使用してみます。

$ time mpiexec -n 4 test1

#######################################################

Master node name: rpisc01

Enter number of segments:

300000

*** Number of processes: 4

     Calculated pi = 3.14159265359071326
              M_PI = 3.14159265358979311
    Relative Error = 0.00000000000092015

real    11m44.018s
user    46m48.134s
sys     0m0.617s

real+sysで約11分45秒なので、処理速度も4倍になりました。

次にスレーブも含めた全てのコアを使って実行してみました。
実行に-n 12 とかの指定ではエラーになりスマートなパラメータの指定方法がわからず、とりあえず-Hで指定しました。

$ time mpiexec -H rpisc01,rpisc01,rpisc01,rpisc01,rpisc02,rpisc02,rpisc02,rpisc02,rpisc03,rpisc03,rpisc03,rpisc03 test1

#######################################################

Master node name: rpisc01

Enter number of segments:

300000

*** Number of processes: 12

     Calculated pi = 3.14159265359072037-
              M_PI = 3.14159265358979311
    Relative Error = 0.00000000000092725

real    5m20.207s
user    17m6.587s
sys     2m8.557s

real+sysで約7分28秒でした。
期待したほどではなかったのですが、1台の時よりは速くなりました。
realの時間は倍以上になっているので、単純な処理では速くなっているのですが、sysの時間が増えてしまいました。
マスター+スレーブ1台の場合でも2分近くかかったので、恐らくサーバ間の通信処理辺りがボトルネックになっていそうです。

並列処理の分野は経験が無く、どう応用すればよいかもわかりませんが、これから遊んでみたいと思います。