Python Hack-a-thonで発表してきました + 発表の補足
Python Hack-a-thon 2011.02で「PyCUDAの紹介」という内容で発表をしました.発表資料はSlideShareにアップしています.
発表時間が短くなったこともあり,説明が雑だった部分も多かったと思うので,喋り足りなかった部分をここで改めて補足します.
発表動機
ここ数年CPU単一コアのクロック数が伸び悩み,「タダ飯が食える時代は終わった」とまで言われる中,GPGPUはマルチスレッド・マルチプロセスプログラミングと同じぐらい重要な技術になっていくかもしれません.しかしながらGPUコンピューティングに関する知識が十分に広まっているとはまだ言えない現状だと思います.マルチコア環境における並行コンピューティングと同様で,GPGPUも「いいプロセッサを使ってるんだから速くなって当たり前」というわけではなく,GPUのアーキテクチャに適したアルゴリズムを考えることが重要です.自分自身がここ1年でGPGPUに触れてそういったことを強く感じたので,今回はより多くの人にGPUコンピューティングを広められたらと思い発表の機会をいただきました.
PyCUDAの利点
PyCUDAではとてもPythonらしい高度な抽象化が実現されているので,煩雑なメモリ操作などを簡略化し,全体として簡潔なコードでGPUコンピューティングを行うことができます.そしてPyCUDAのSourceModule用に書いたカーネル関数はそのままC言語の環境に持っていくことが可能です.GPUコンピューティングで性能を出すために重要なのはもちろん,GPU上で実行されるカーネル関数のチューニングです.CPUで行っていたある処理をGPU上で処理させてどの程度高速化できるかは,試してみないとわからないという部分があります.そこで,まずPyCUDAを使ってカーネル関数のチューニングを行うという使い方が考えられます.PyCUDAで十分な性能が出ないのなら,CやFortranで書き換えても十分な性能は得られないかと思います.まずはPyCUDAでGPUコンピューティングを体験してみるのはいかがでしょうか.
また,複数GPUを使った処理や複数マシンを使った処理をするときにもPythonを使えば比較的簡単に書けるかもしれません.
GPUArray
GPUArrayを使ったプログラミングをコメントを入れつつ少し解説します.
>>> import pycuda.autoinit # デバイスの初期化などをしてくれる >>> from pycuda import gpuarray >>> import numpy >>> a = numpy.random.rand(1000000).astype(numpy.float32) # ホスト側データ >>> gpu_a = gpuarray.to_gpu(a) # ホストからデバイスへ転送 >>> n = numpy.random.rand(100, 100).astype(numpy.float32) >>> gpu_b = gpuarray.to_gpu(b) # 多次元でもOK >>> gpu_a *= 2 # numpyのarrayのように演算するとGPU上で並列実行される >>> gpu_c = gpu_a + 2 # gpuarrayを直接生成できる >>> from pycuda import cumath # GPU上で並列実行される数学ライブラリ >>> gpu_c = cumath.sin(gpu_c) >>> c = gpu_c.get() # デバイスからホストへ転送 >>> print type(c) # numpyのarrayとして返ってくる <type 'numpy.ndarray'>
どうしてもデバイスホスト間のデータ転送はボトルネックになるので,シンプルな処理だとデータが十分に大きくなければnumpyの方が速くなってしまいます.データ転送は最小限に抑えましょう.