GPUをGPGPU(汎用計算)目的で操作する方法は、CUDAとOpenCLが有名です。
ただし、CUDAはNvidiaのGPUでしか使えませんし、OpenCLはGPU専用ではないのでとっつきにくいです。というわけでNvidiaのGPUがあるなら最初はCUDAをオススメします。どちらも、C言語をベースにした言語でプログラミングします。
CUDA
CUDA言語は、C言語の拡張で、CUDA ToolKitに含まれるnvccコンパイラを用いてコンパイルします。
__device__ や __host__ を記述することで、関数がGPUで使えるのか、CPUで使えるのか定義できます。
GPU処理の起点
CPU側のコードからCUDAランタイムAPIを呼び出して、__global__が記された関数をGPUで実行させることができます。上記の例だと、tidは何番目の処理かに相当する。
JavaからGPUを動かす
Javaコードを直接GPUで動かせるライブラリはAparapiくらいしかありません。Aparapiはビルドが少々難しいうえ、GPUの限られた機能しか使えません。
そこで、JavaコードからCUDAランタイムAPIを呼び出すことを考えます。JavaコードでCPU処理部分を記述し、GPU処理部分はCUDA言語で記述します。
JavaコードからCUDAランタイムを呼び出せるライブラリ
JCuda
おそらく最もライブラリとして完全です。今回はスルー
lwjgl.Cuda
LWJGLはゲームライブラリですが、GLからCUDA、ほかにも沢山組み合わせることができ、Minecraftでも利用されています。Maven一発で入れられるのもいい点です。
LWJGLからCUDAを呼び出すサンプルはこちらが参考になります。
内容はこんな感じです。
注意点
- 最初のCUDAファイルは文字列で渡してコンパイルしてもらう
- Java側でデータはスタック領域に配置しなければGPUメモリにコピーできない
- スタック領域では明示的なメモリ開放が必要
- 一次元配列以外のデータを渡すのはけっこう面倒
CUDAでのベクトル関数はこちらが便利