SPUスレッドの非同期実行

計算のための実行カーネルができたので、これを並列化することが目標となるが、言うのは簡単だが実行するのは非常に大変だった。
なんと言ってもlibspe2ではSPUスレッドの準備と実行に多くのステップが必要な上、スレッドの実行はデフォルトでは非同期には行われない。つまり順番にスレッドを立ち上げるプログラムを書いただけでは、SPUの一つ一つが処理が終わるまで待って次を実行するという、全く並列処理を行わないプログラムになってしまう。
これを解決するにはPthreadライブラリの利用が必要なのだが、ただでさえ手順が多い上に管理が面倒なSPUのプログラムに、低レベルな管理を行わなければならないPthreadの面倒までみなければいけないのでは気が重くなる。

どうせこれからも必要になるだろうと思い、まず非同期実行を行うクラスである、async_spe_threadクラスを(汎用性のためにCで)記述した。このクラスを用いた手順は以下のようになる。

  1. SPUプログラム(ELF形式)をオープン (spe_image_open)
  2. async_spe_thread__newの第一引数としてSPUプログラムを渡してインスタンス化する
  3. データの受け渡しが必要ならばasync_spe_thread__set_dataで指定する
  4. async_spe_thread__runで実行
  5. メールボックスを用いた通信が必要ならasync_spe_thread__send_message, async_spe_thread_receive_messageで通信
  6. async_spe_thread__joinで終了の待機
  7. async_spe_thread__deleteで破棄

個人的な利用のため、エラー処理はほとんど何もしていないが、今回の目的のためには十分だ。モデルとしてはJavaのようにnew->run->join->deleteで非同期実行されるようにしている。また安定的に動くかどうか不安だが、SPUプログラムのロードのオーバーヘッドをさけるため、run->joinは何度も繰り返す事ができるようにした。