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分近くかかったので、恐らくサーバ間の通信処理辺りがボトルネックになっていそうです。
並列処理の分野は経験が無く、どう応用すればよいかもわかりませんが、これから遊んでみたいと思います。