javaで簡単にgpgpu aparapi
TRANSCRIPT
Java で簡単に GPGPU-Aparapi-
2012/10/13関西 GPGPU 勉強会
1
自己紹介
• 先山 賢一 – @ksakiyama134
• 同志社大学大学院 工学研究科 M2– 研究: 人工社会 + GPGPU みたいなこと– T 研ではないです
• バイクと OpenCL が好き– 最近は Ruby とか興味あり
2
GPGPU 歴• 2010 年 10 月
– OpenCL を勉強するも難しくて諦める
• 2011 年1月– CUDA を勉強
• 2011 年9月– OpenCL を再勉強 (OpenGL も少し )
• 2012 年3月– GPGPU 関連で論文発表
3
発表の流れ
• GPGPU– OpenCL
• Aparapi–プログラミング–パフォーマンス・チューニング–デモ
• まとめ4
GPGPU
• General Purpose computing on GPU– GPU のパワーを画像処理以外に応用
• GPGPU を使うためには– CUDA– OpenCL– C++ AMP– OpenACC etc…
5
OpenCL
• 並列計算の標準フレームワーク– Open Computing Language
• OpenCL C 言語–並列アルゴリズムを記述するための言語
• C/C++– API を使用して OpenCL C のコードを実行
6
7
OpenCL を勉強したいが…
1. C++ とかいやなんですけど…– 他の言語を使いたい
2. 並列アルゴリズム , データ転送以外の部分でコード数が多い– もっと簡単に書きたい
8
1. 他の言語でできない?
• 賢い方々がつくったラッパーを使おう!!• PyOpenCL• Ruby-OpenCL• PHP OpenCL など
• もちろん Java でもあります!• JavaCL• JOCL
9
そ、
そんな
便利なものが
たくさん
10
ContextDevice
• 残念ながら…最低限の知識は必要– context– command-queue– buffer– kernel
2. もっと簡単にできない?
Host
CommandQueue
Buffer
Kernel
OpenCL C コードは文字列
__kernelvoid square(__global float *dst, __global float *src){ int gid = get_global_id(0); dst[gid] = src[gid] * src[gid];}
kernel_source = <<EOF__kernelvoid square(__global float *dst, __global float *src){ int gid = get_global_id(0); dst[gid] = src[gid] * src[gid];}EOF
.... 省略
ホストコードOpenCL C
結局は C みたいなコードを書く
例: Ruby
11
12
そこで Aparapi!
Aparapi
• A Parallel API– http://code.google.com/p/aparapi/
• Java で並列アルゴリズムが書ける– OpenCL C を書かなくてよい!
• AMD が開発– NVIDIA GPU でも動きます
13
Java と OpenCL
• Aparapi 以外にも– JavaCL– JOCL
• しかし Aparapi はこれら2つより 圧倒的にコード数が短くて済
む
感覚: Aparapi >>> JavaCL > JOCL14
使い方
import com.amd.aparapi.Kernel;
new Kernel() {@Override public void run() {
int gid = getGlobalId();c[gid] = a[gid] + b[gid];
}}.execute(size);
15
16
すごくシンプル
17
Aparapi, JavaCL, JOCL,実装してコード数を比較してみました
18
kernel.execute(size);
最初の実行?Yes
OpenCL が入ってる?
バイトコードをOpenCL C に変換でき
た?
OpenCL で実行!
OpenCL が入ってる?
No
Java Thread Pool で実行
No
No
Yes
Yes
Yes
19
バイトコードって?
• Wikipedia より–仮想マシンによる実行のために設計された、
実行可能なプログラムのバイナリ表現である
• Java バイトコード– Java のコンパイラが生成するコード– JVM のインタプリタによって
ネイティブコードに変換されて実行される
20
Aparapi の主な制限
• 1次元配列のみ– final をつける– Primitive なデータ型のみ
• Float, Double, Integer など使用不可• ArrayList など使用不可
• switch, break, continue など使用不可– JTP で実行される
• run() 内で new できない
※ 詳しく知りたい方は JavaKernelGuidelines を参照
21
パフォーマンス・チューニング
• ローカルメモリ– @Local修飾子– 1次元配列のみ
• 同期– localBarrier(), globalBarrier()
• Range class– NDRange のサイズを細かく指定– execute( Range.create2D(w,h,16,16) )
22
デモ
• 正方行列の乗算
• バイトニックソート
• GUI との連動
23
自動でデータ転送される
for (stage = 0; stage < numStages; stage++) { execute( Range.create(size, 256) );}
for (stage = 0; stage < numStages; stage++) { // memcpy: Host -> Device execute( Range.create(size, 256) ); // memcpy: Device -> Host}
24
データ転送を操作する
setExplicit(true);put(array_a).put(array_b).put(array_dst);
for (stage = 0; stage < numStages; stage++) { execute( Range.create(size, 256) );}
get.(array_dst);
25
まとめ
• Aparapi で簡単に並列プログラミング–深く OpenCL を学ぶ必要がない
• データ転送に注意する– setExplicit(true), put(arr[]), get(arr[])
• もっと詳しく知りたい人は– http://code.google.com/p/aparapi/
26
ご清聴ありがとうございました