MITでやってるCellプログラミングの講義。
Selected Projectsを見ると、
Global Illumination や Distributed Realtime Ray Tracer 、Speech Synthesizer 等、骨のありそうな課題が並んでいます。
てか、普通に組むのでも結構大変じゃん、この課題。
ほんとに1ヶ月で、他にも講義とかあって忙しいはずなのに、
Cell向けにマトモに最適化されたものができるの?
(最悪PPUしか使いませんとかなら分かるけど)
そこまでMITは優秀なのか!?
それとも若さゆえの勢いなのか!?
くそっ、嫉妬してしまうぜ、奴らの若さと才能に。
てことで、そろそろ課題が出来上がって、webに公開されるのかも。楽しみ。
レンダリング系だと、巨大なメッシュやテクスチャの扱いが面倒ですし、GIをやろうとすれば、
テンポラリの領域も相当な大きさが必要になるでしょう。
ベクタライズなんて根性があれば誰でもできますが、
256KBの空間とDMAを駆使してプログラミングするのは、
かなりの障壁です(そこも慣れと根性なのかもしれませんが)。
巨大なメモリへのランダムアクセスが苦手というのが、SPUの最大の弱点ですねえ。
かといって、LSの代わりにキャッシュを載せたところで、ロジックやタグが載るので、
128KB程度のI/D混載キャッシュしか載らないとすると、どう考えても性能が出にくいので、
やっぱり今の設計で正解か。
いや、6コアでキャッシュ256KBが一番(楽で)良かったんじゃないかな。うん。
(ピーク性能は落ちますがね)
そこらへんの大変さは、当然IBMも分かっているわけで、
SDK2.0をみると、software managed cache や spu code overlay といった、
プログラマの負担を減らしてくれるライブラリが新たに提供されています。
software managed cacheは、
a = cache_rd(name, addr_a);
b = cache_rd(name, addr_b);
cache_wr(name, addr_c, a + b);
といったように、読みの場合、グローバルアドレスを与えると、
キャッシュに載っているかを判定し、載っていなかったらDMAでローカルに持ってくる、
載っていたらローカルにある値を返す、という処理を行います。
キャッシュはWAY数やTAGの定義をプログラム毎に変えられます。
name を変えることで、複数のキャッシュを持たせ、効率をあげることができます。
ってさあ、重いよね、明らかに。ヒットしてもソフト的な負担が相当に重い。
なにせ、ハードのキャッシュはアドレスと大量のタグとの比較を並列処理で一瞬で終わらせてるから、
それをソフトでやるのはどうしても相対的に厳しい。
それを改善するために、LS上のキャッシュラインをロックして、
ライン単位でしか判定処理を行わないというインタフェイスも用意されている。
それなら速いんだけど、ラインのアラインの問題もあるし、使いにくさは残る。
どのみちポインタを辿る様な処理はかなり煩雑な手続きになってしまう。
また、ライン単位のようにアクセスの粒度が大きいことが始めから分かっていれば、
最初からDMAを使えばいい気もする。
といっても、DMAより扱うのは楽になるので、そういった意味で存在価値はあるが。
キャッシュでも、次にアクセスするブロックが予測できるなら、
予めtouchしてprefetchしておけば、
DMAのダブルバッファとほぼ同等の効果が得られるので、
やっぱLSじゃなくてキャッシュでも良かったのではないかと、若干思うんだよなあ。
そこらへんの設計思想は難しいね。
code overlayに関しては、
SIJAMのblogが詳しいです。
要は、関数を mov ax,xxxxh int 21h のような感じに、番号+callで呼ぶようにします。
callされたら、目的の関数がLSに載っているかを調べ、載っていなかったらLSにDMAします。
また、callだけでなく、retする時も、戻り先の関数がLSに居るかを確認しなければなりません。
結構な大技です。
(ほんとは、もっといろんな処理してますが、詳しくはリンク先で)
以上、
d-cache代わりに software managed cache,
i-cache代わりに code overlay
という選択肢もあるよ、という話でした。
よろしくお願いします。(社会人的な癖)