SPUスレッドの非同期実行
計算のための実行カーネルができたので、これを並列化することが目標となるが、言うのは簡単だが実行するのは非常に大変だった。
なんと言ってもlibspe2ではSPUスレッドの準備と実行に多くのステップが必要な上、スレッドの実行はデフォルトでは非同期には行われない。つまり順番にスレッドを立ち上げるプログラムを書いただけでは、SPUの一つ一つが処理が終わるまで待って次を実行するという、全く並列処理を行わないプログラムになってしまう。
これを解決するにはPthreadライブラリの利用が必要なのだが、ただでさえ手順が多い上に管理が面倒なSPUのプログラムに、低レベルな管理を行わなければならないPthreadの面倒までみなければいけないのでは気が重くなる。
どうせこれからも必要になるだろうと思い、まず非同期実行を行うクラスである、async_spe_threadクラスを(汎用性のためにCで)記述した。このクラスを用いた手順は以下のようになる。
- SPUプログラム(ELF形式)をオープン (spe_image_open)
- async_spe_thread__newの第一引数としてSPUプログラムを渡してインスタンス化する
- データの受け渡しが必要ならばasync_spe_thread__set_dataで指定する
- async_spe_thread__runで実行
- メールボックスを用いた通信が必要ならasync_spe_thread__send_message, async_spe_thread_receive_messageで通信
- async_spe_thread__joinで終了の待機
- async_spe_thread__deleteで破棄
個人的な利用のため、エラー処理はほとんど何もしていないが、今回の目的のためには十分だ。モデルとしてはJavaのようにnew->run->join->deleteで非同期実行されるようにしている。また安定的に動くかどうか不安だが、SPUプログラムのロードのオーバーヘッドをさけるため、run->joinは何度も繰り返す事ができるようにした。