検索RubyでOpenCLを試してみた2011年05月31日OpenCL?MacOSX10.6では、OpenCLというGPUを扱うための環境が標準で搭載されています。私のMacbookPro(2009Midモデル)ではGeForce9400Mが付いていますが*1、OpenCLを使うことで並列計算処理にこのGPUを利用することが出来ます。GPUはCPUに比べ多くのコアを搭載しており、これを利用することで並列計算速度の大幅な向上が期待できます。同様のGPGPU技術としてNVIDIA向けのCUDAが存在しますが、OpenCLはNVIDIA製GPU以外のデバイス(ATI製GPUやCell/B.E.等)にも利用できるなど、異種混合な環境での動作を主眼に置いているようです。RubyでOpenCL本来OpenCLを利用するにはXCode開いてC言語で色々書いて...という処理が必要なのですが、今回はBarracudaというOpenCLのRubyBinding*2を利用することで、簡単にOpenCLを利用してみました。OpenCLでは、GPU等のデバイスに処理を依頼する『ホスト側』のコードと、依頼されたデバイスが行う処理である『デバイス側』のコードの記述が必要になります。Barracudaを使うことで、この『ホスト側』のコードは全てRubyで記述することができます。『デバイス側』のコードは文字列OpenCL-C言語のコードを書いて渡すような形式になります。10.6環境にインストールします。自分の場合RVMでRubyを入れているため、インストールスクリプトに少し変更が必要でした。installHelloWorldまずは並列計算とは全く関係なく、単純にGPUを利用してHello,world!を表示してみます。OpenCL-C言語には標準入出力が無いため、デバイス側で生成した文字列をホスト側で受け取って出力します。GPUを利用するための初期化処理等は全てBarracudaが行ってくれるため、実際の処理にのみ注力してコードを記述できます。次は並列処理をCPUとGPUそれぞれに任せて、比較してみます。モンテカルロ法を用いてn回の試行でdim次元球の体積を求めるというプログラムを作りました。8.958749=end次元数dimが少ない状態ではCPUの方が高速ですが、dim=64辺りからGPUの方が高速になっています。試行回数をn=1000(立方体の中に1000個の点を置いて半径内外で判断)で試して更に10回の平均を取っていますが、nの数が増えるに従ってその差は顕著に現れると思われます(但しGPUのコア数や転送量の関係でどこかで頭打ちになる)。注意点なお、GPU内でOpenCL-C言語を用いて乱数を生成する方法が分からなかったので、乱数配列を渡しています。書籍『OpenCL入門』にMersenneTwisterで乱数を生成する実装が書いてあったのですが、上手く利用できませんでした。本家MTのC言語実装であるmt19937ar.cも、そのままでは動かせず*3、乱数を生成する種となる『状態』の並列化を考えないといけない等の問題があったため、利用できませんでした。まとめ以上、Barracudaを利用してOpenCLをRubyで扱う方法を簡単に説明しました。InstanceでRubyを利用して簡単にジョブオフロードを行うようなことも出来るのではないでしょうか。OpenCLの情報は日本語圏ではまだ乏しく、ましてRubyBindingの情報など恐らく皆無ですが、何かの参考になれば幸いです。最近のMacではOpenCL環境をOS標準機能としてサポートしているようなので、興味がある方は是非利用してみてブログ等でアウトプットして頂ければと思います。Gist1:システムプロファイラ等で確認できます2:OpenCLをRubyで記述できるようにしたもの*3:OpenCL-C言語で対応していない計算箇所がどこかにあるのかも。具体的にはTempering直前辺り。