Red Books
絶滅危惧種に関係ありそうな感じだけど、これは IBM が出している資料のこと。White Paper に対抗しているのかな?
こんなのをダウンロードして印刷してみた。全部で600ページくらいあるんだよ。すごいボリューム。近日中に読破しようと思います。
絶滅危惧種に関係ありそうな感じだけど、これは IBM が出している資料のこと。White Paper に対抗しているのかな?
こんなのをダウンロードして印刷してみた。全部で600ページくらいあるんだよ。すごいボリューム。近日中に読破しようと思います。
libspe2 になってからの処理はコンテキストが単位になることは前のブログで述べた通りだ。spe のイメージをそのままファイルから取り込んで展開する API があるのだが、それだとうまく動作しなかった。仕方がないので、サンプルコードのとおりにやることにした。これをベースに少しづつ、肉付けしていこうと思う。動くものがないと始まらないのだ。
Fixstars からは CTK0.73 がリリースされていた。CTK そのものは、ビルドが出来てインストールまで問題なくできるのであるが、サンプルコードのビルドでいつもしくる。どんなことが出来るかはサンプルを見ればわかるし、こういうのを見てると色々な技を組み合わせて、新しい技法を生み出すことも出来る「宝の山」なのだ。
とりあえず、明日は複数スレッドの立ち上げと、仮想環境での開発環境の構築を目標にする。時間がないのだ。
昨日に引き続き、cell のプログラミング方法について色々と調べてみる。IBM のウェブサイトに日本語でばっちり解説があったので載せておく。これと DMA を組み合わせれば、オーバーヘッドの少ない簡単なスケジューラが作れそうだ。なるべく、計算そのものを SPE にやらせるようにして、他の処理(スケジューリングとかデータベースへのアクセスとか)を PPE にやらせるようにするのだ。
タイマ(フリーランニングカウンタ?)の値もアクセスできるので、これを使って経過時間を測定する。これはストップウォッチに相当するような機能だ。測定したい手前でスタートして、そのルーチンを通過したところでストップさせるわけだ。ハードウェアで計測するのでかなり正確に測定できそうだ。
CBE(Cell Broadband Engine) の SDK は Ver.3.0 が最新版なんだけど、これで使うライブラリに libspe がある。libpspe1 まではスレッドが割とお手軽にコンテキストと一緒になって生成できた。
libsp1 だとこんな感じだったのだ、
FixStars のサンプルコードより抜粋、
/* SPEスレッドの生成とスタート */
printf("Create and Start spe program\n");
for (i = 0; i < SPE_NUM; i++) {
spe_id[i] =
spe_create_thread(0, spe_handle[i], (void *) &dma_data[i],
NULL, -1, 0);
if (spe_id[i] == 0) {
printf("[ERR] Can't create spe%d thread\n", i);
return -1;
}
}/* PPEプログラムはフラグをSPEプログラム毎にSPE_STARTに設定 */
for (i = 0; i < SPE_NUM; i++) {
dma_data[i].flag = SPE_START;
printf("%d:flag=%d\n", i, dma_data[i].flag);
}/* SPE_DONEに変わるまで待つ */
for (i = 0; i < SPE_NUM; i++) {
while (dma_data[i].flag != SPE_DONE);
/* SPEプログラム処理終了後のフラグ */
printf("%d:flag=%d\n", i, dma_data[i].flag);
}for (i = 0; i < SPE_NUM; i++) {
/* SPEスレッドの終了待ち */
printf("Waiting spe%d program is finish...", i);
spe_wait(spe_id[i], &status[i], 0);
printf("done\n");/* SPEスレッドの破棄 */
printf("Relese spe%d program\n", i);
spe_close_image(spe_handle[i]);
}
libspe2 になってから大きく枠組みが変わった。(これが一番かわったところと言っても良いかもしれない。)自前で pthread を用いて、書かなければいけなくなった。これ、けっこう俺的には面倒くさい。なぜなら、libspe2 だと spe に仕事を投げる時にブロックしてしまうからだ。以下のメソッドを使って spe に投げる
spe_context_run(spe, &entry, 0, NULL, NULL, NULL);
spe で完了するまで戻ってこないから、戻って来たのを監視するスレッドを立ち上げないと行けないというわけだ。これ以外にもやり方はもちろん色々あって spe を自律的に動かすような仕組みもある。俺的には spe のオーバーヘッドを小さくする意味で、ppe のスレッドによるスケジューリングをやりたい。
年が明けてから、ずーっと SPE のうまい動かし方を考えている。まぁ、あまりうまくないとしても痛い使い方はしたくない。SPE の使いこなしってマイコンでのソフトの組み方に似ている。自分でスケジューラを組んで、タスクをディスパッチしていく。
今、考えているやり方は関数一つ一つに SPE を割り当ててしまうこと。一つの大きな仕事を複数の SPE でこなすのではなくて、処理を丸ごと一つあるいは二つ割り当ててしまうわけだ。静的なスケジューリングと言えなくもない。当然、各SPE で処理の重さが変わるわけだけど、そこは PPE ががんばるわけだ。各 SPE の処理の終了時に結果を返して次のデータをセットする。これをラウンドロビン方式で処理していく。
PPE は入出力と SPE をキックするだけになる。SPE の処理は予め抽象化しておき、普通のPCで充分に処理を枯らしておく。プロファイリングも欠かせない。ソースコードレベルの最適化は普通のPC環境で出来るので、チューニングはなんとかなりそうだ。
面白くなって来た。早速、テストプログラムでも書いてみるか。