研究日誌。

大規模なグラフ処理に対してメモリ階層構造を考慮した高性能なソフトウェアを開発。

行列積演算2。

2007-08-18 17:29:20 | Weblog
■Cell への適応■
実験1、2より、512 x 512 という比較的小さな行列の積演算においても、かなりの速度向上が見られた。サイズを大きくすればよりその効果は得られるだろう。さらに複数 SPE を用いて処理させて、高速化していきたい。

考慮しなければならないことがいくつかあるが、やはり SPE に載るデータ量である。SPE の LS は かなり小さく、実行するためのバイナリも含めて 256KB しか格納できない。double の 512 x 512 の行列1つだけでそのほとんどを占領してしまう。

このことから「オリジナルの入力行列2つを格納し、決められた場所を演算させる」といったことは物理的に不可能である。よって必然的に「処理に必要な部分を DMA 転送でもらってきて演算して返す」といったスタイルになっていく。

すでに2つめの入力行列Bは転置されているため、i 行 j 列目の要素は、Aの i 行目とBの j 行目を内積することで求められる。行列A、Bからそれぞれ1行ずつ SPE へ DMA 転送し、内積を行いその結果を PPE へ返すことになる。今回はより大きなサイズの行列を扱えるように1要素ずつ演算することにする。

大まかにはつぎのような流れで処理を行うことになっている。


[PPE]
1.SPE の準備をする。
2.割り当てられるのを待っている SPE を探し、パラメータを割り当てる。
  
 [SPE]
 1.DMA 転送しながらパラメータを受け取り、フラグがスタートになるのを待つ。
 2.演算に必要な行列2つを、少しずつ DMA 転送し、演算していく。
 3.処理が終われば、DMA 転送にて、結果を [PPE] へ戻す。
 4.1~3をフラグがストップになるまで繰り返す。
   (SPE スレッドは起動したままにする)
 [SPE]
  
3.処理の終わっている SPE から結果を受け取り、格納する。
4.すべての処理が終わるまで繰り返し、終わるとフラグをストップにする。
5.SPE の後処理を行う。
[PPE]


実行してみると演算しないで処理が終了してしまう要素がいくつかあるときがある。毎回違う要素で、うまくいくこともある。調べてみるといくつかの要素を複数回計算してしまい、その分演算していない要素ができてしまったようなのである。

同期処理にはフラグを用いてるのだが、どうもうまく機能していないのかも知れない。デッドロックのようなものが起きてしまい、処理が終わっていないうちに新たなパラメータを振り分けられてしまっているのかもしれない。いずれにしてもどうにかデバッグしていくしかない。





※マンデルブロにおいても同じようなことが確認。
何度も描いてみるとうまくいかないときもあることを確認した。また描画するサイズを 512 x 512 ではなく、4096 x 4096 のように大きくすると、演算ができていない箇所が増えてくる。もちろん毎回失敗するわけでもなく、成功することがあるため、原因を見つけるのが難しい。