Cell での BLAS 、特に DGEMM(C←αAxB+βC)を作成しているが、なかなかうまくいかない。以前は行列サイズ 2048x2048 で固定していたが、それでは使いづらいので動的にメモリ確保することにした。
PPE にてアラインされたメモリを動的に確保したいときは、次のように行う。
posix_memalign(void **matrix_ptr, alignment, column_size * row_size * sizeof(double));
また、SPEは LS が 256Kbyte しかないため、静的に確保してしまった方がよいだろう。
行列を1次元の配列で表しているため、行ごとにはアラインされているが、列ごとには飛び飛びになってしまっている。
DMA 転送ではアラインされていないといけないので、LS に行列が乗ってしまう場合をのぞいては、
あらかじめ、B行列(C←αAxB+βC)を転置するなどといった補正をかけることになる。
そうすれば、「行列Aの第i行と行列Bの第j列の内積」という演算は
「行列Aの第i行と行列Bの第j行の内積」とみることができる。
ある程度大きなサイズでないと、
SPE スレッドの起動、転置、DMA 転送などのオーバーヘッドが伴ってしまうため、
SPE に切り出すことは意味のないことになってしまう。
xlc、double-buffer 等は用いていないので、さらに高速化は可能だが、うまく動いているかものすごく怪しい。
以下はその実行時間である。
Play Station 3
CPU : Cell 3.0GHz
Mem : 256Mbyte
Compiler : ppu-gcc spu-gcc
2048x2048 : 1250 [msec]
1024x1024 : 190 [msec]
512x 512 : 45 [msec]
PPE にてアラインされたメモリを動的に確保したいときは、次のように行う。
posix_memalign(void **matrix_ptr, alignment, column_size * row_size * sizeof(double));
また、SPEは LS が 256Kbyte しかないため、静的に確保してしまった方がよいだろう。
行列を1次元の配列で表しているため、行ごとにはアラインされているが、列ごとには飛び飛びになってしまっている。
DMA 転送ではアラインされていないといけないので、LS に行列が乗ってしまう場合をのぞいては、
あらかじめ、B行列(C←αAxB+βC)を転置するなどといった補正をかけることになる。
そうすれば、「行列Aの第i行と行列Bの第j列の内積」という演算は
「行列Aの第i行と行列Bの第j行の内積」とみることができる。
ある程度大きなサイズでないと、
SPE スレッドの起動、転置、DMA 転送などのオーバーヘッドが伴ってしまうため、
SPE に切り出すことは意味のないことになってしまう。
xlc、double-buffer 等は用いていないので、さらに高速化は可能だが、うまく動いているかものすごく怪しい。
以下はその実行時間である。
Play Station 3
CPU : Cell 3.0GHz
Mem : 256Mbyte
Compiler : ppu-gcc spu-gcc
2048x2048 : 1250 [msec]
1024x1024 : 190 [msec]
512x 512 : 45 [msec]