GPUによる行列積の性能

まず、お断りしておくが、筆者は3Dゲームをやらないので、ハイエンドのGPUは地球に優しくないということで、消費電力があまり大きくなく、ファンレスの8600 GTを使っている。このGPUはマルチプロセサが4個であり、ハイエンドのGPUと較べると、演算器の数で1/4、クロックで1/1.5程度であり、ピーク性能としては1/6程度のGPUである。

SDKに含まれている行列積のProjectは、BLOCK_SIZE=16で、行列のサイズはその倍数で、行列Aは80行×48列、行列Bは48行×128列となっている。この行列積は、行列Cの1要素に48回の積和演算を必要とし、それを80×128要素について計算するので、積和演算が49万1520回、浮動小数点演算回数はその2倍の983040回である。これを8600 GTで実行すると、0.175msで終了した。これは約5.6GFlopsに相当する。

8600 GTは、シェーダークロックが1180MHzでマルチプロセサが4個であるので、ピーク性能は3×32×1180=113GFlopsであるが、それに比較すると5%程度の性能しか実現できていない。行列を大きくすると、シェアードメモリへの転送量の増加に較べて、演算数の増加の方が大きいため演算性能が向上するので、行列サイズを変えて測定を行ってみた。その結果を次の表に示す。

行列A 行列B 演算量 実測時間 [ms] 実効性能 [GFlos] ピーク比
80×48 48×128 983040 0.175 5.62 0.0496
160×96 96×256 7864320 0.701 11.2 0.099
320×192 192×512 62914560 4.248 14.8 0.131
640×384 384×1024 503316480 29.11 17.3 0.153
1280×768 768×2048 4026531840 220.7 18.2 0.161
2048×2048 2048×2048 17179869184 924.0 18.6 0.164

予想されたように、行列のサイズを大きくすると性能は向上し、2048×2048の行列同士の積では18.6GFlopsとなった。しかし、これでもピーク性能に対する比率は17%弱であり、演算以外の処理にかかる時間が大きな比率を占めているようである。