研究日誌。

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

内積プログラム。

2007-08-06 12:54:21 | Weblog
Cell を 用いて大きなベクトルの内積プログラムを書いてみた。

行列のサイズが大きくなっていくと、PPE か SPE いずれかが DMA 転送できるサイズに分割してあげなくてはならない。というのも DMA 転送は最大サイズが 16 kbyte であるためである。様々なところで PPE の処理能力がボトルネックであるとさんざん聞いてきたので、PPE には「各 SPE に担当させる範囲の割り振り」、「各 SPE からの処理結果の統合」といった最小の Job のみにとどめるようにした。SDK 2.1 の Sample の Euler Particle-System Simulation がとても参考になった。

■前提
・ベクトルのサイズはある程度大きく、SPE にのらない。
・ある程度の精度が必要であるため、Cell の得意とする float ではなく double を用いる。
・処理に用いる2つのベクトルはともに double 配列で用意する。
・内積結果は単に double で格納する。

■流れ
[PPE]処理に用いるベクトルの用意

[PPE]各 SPE が担当する範囲を「 DMA 転送に用いる構造体」に格納する。

[PPE]spe_context_create 、 spe_program_load 、 pthread_create で SPE Program を実行。

 [SPE]まずは「構造体」を DMA 転送し、パラメータを得る。

 [SPE]担当する範囲が終わるまで、2つのベクトル を DMA 転送し、内積演算する。

 [SPE]最終的な内積結果を PPE へ DMA 転送で返す。

[PPE]pthread_join で SPE の終了待ち。

[PPE]各 SPE の内積結果を1つにまとめる。


実行結果を見てみると、うまくいっているようだ。かなり小さい桁では若干の誤差があるが、 double の精度よりもさらに小さいところであるので、無視してよいだろう。また実行時間計測してみて、SPE 1つ1つの実行はかなり高速であるのだが、全体ではあまり早くない。やはりスレッド起動に時間がかかっているか、サイズを変えても全体の実行時間はあまり小さくならない。100要素でも、1000000 要素でも、6 [msec] ほどかかってしまう。まずは SPE Program を double buffer ver. にするなどいろいろ試してみることにしよう。