OpleCLによるGPGPU 記事一覧
実際のコードは次の項目(OpenCLによるGPGPU入門②)を参照の事。
一応簡単な計算ができたので記事にまとめておく。
本当は本は使わない予定だったのだが、
結局図書館でOpenCLに関する本を借りてきた。
以下その二冊。
OpenCL入門 - マルチコアCPU・GPUのための並列プログラミング
http://www.fixstars.com/ja/news/books/opencl/
サンプルのダウンロードページ
amazon
amazon(改訂版の方)
借りてきたのは改訂前の古い版。
OpenCL入門 GPU&マルチコアCPU 並列プログラミング
http://www.shuwasystem.co.jp/products/7980html/2608.html
サンプルのダウンロードページ
amazon
こちらの本の方が、説明が丁寧で入門者向きだとおもう。
ただし、既に絶版。amazonではまだ買えそう。……どうしよう。
語句の確認
GPGPUに関連する語句の説明(GPGPUがやりたい。①)
GPGPUをする事の出来るプラットフォームはなにもOpenCLだけじゃない……と言う話。
開発環境のインストール
開発環境の整え方および今回参考にした記事(GPGPUがやりたい。②)
私の場合はAMDなので、
AMD-APP-SDK-v2.9-Windows-64.exe
をインストールした。
以下、OpenCL Cプログラミングの流れ。
1.プラットフォームのIDを取得する。
……「clGetPlatformIDs()」関数
要するに、どこのメーカーの出しているプラットフォームを使うかを選択する。
今回は、AMDのGPUを使うので、AMDの「OpenCL 1.1 AMD-APP-SDK-v2.4 (650.9)」を選択する。
2.デバイスのIDを取得する。
……「clGetDeviceIDs()」関数
[1.プラットフォームのIDを取得する。]で取得したプラットフォームのIDから、
アクセスできるデバイスを選択する。
3.コンテキストを作成する。
……「clCreateContext()」関数
このコンテキストに、OpenCLに必要な様々な情報を格納する。
噛み砕いて言えば、ファイル操作をするときのファイルポインタ(FILE*)のようなもの。
(あるいは、情報を格納する構造体。)
4.プログラムを文字列としてロードし、コンパイルする。
「OpenCL C言語」 で記述された、GPUで計算させるための、"カーネル"
と呼ばれるプログラムをロードする。
(OpenCLでは、C++のコード中でコンパイルする必要がある。
これは様々なハードウェアとの互換性を確保するためでもある。
また、コンパイル済みのデータをロードし実行する事もできる。)
<<4.1ソースコードからコンパイルして実行する。>>
4.1.オンラインコンパイル
ソースコードの状態のプログラムをロードする。
4.1_1.プログラムを文字列としてロードし、プログラムオブジェクトを作成する。
……「clCreateProgramWithSource()」関数
4.1_2.プログラムをビルドする。
……「clBuildProgram()」関数
4.1_3.次回以降オフラインコンパイルを使用する場合は、ビルド済みのバイナリデータを保存する。
(ただし、カーネルプログラム(GPU側のプログラム)を変更した場合は、再度オンラインコンパイルが必要。)
詳細のメモ書きは、「GPGPUがやりたい。③」参照。
……「clGetProgramInfo()」関数
<<4.2既にコンパイル済みのデータをロードして実行する。 >>
( 先に[4.1]でコンパイルし、バイナリを保存している事が前提となる。 )
4.2.オフラインコンパイル
ビルドされた状態のバイナリファイルをロードする。(そのため、当然オンラインコンパイルよりもビルドに掛かる時間だけ高速。(だと予想しているが、確認はしていない。))
4.2_1.プログラムをバイナリデータとしてロードし、プログラムオブジェクトを作成する。
……「clCreateProgramWithSource()」関数
4.2_2.プログラムをビルドする。
……「clBuildProgram()」関数
5.カーネルオブジェクトを作成する。
……「clCreateKernel()」関数
おそらく、カーネルプログラムに記述した、GPU上で動作させる関数を実体化する作業。
6.メモリオブジェクトを作成する。
……「clCreateBuffer()」関数
おそらく、GPU上のメモリに、必要なメモリを確保する作業。
C言語を使ってCPU上で計算させる時に、「int Buffer;」などとしてメモリを確保するのと同じ。
この時に、一緒に計算させる値をGPU上のメモリに転送する。
7.カーネル関数の引数を設定。
……「clSetKernelArg()」関数
で確保したメモリを、カーネル関数の引数にセットする。
8.コマンドキューを作成する。
……「clCreateCommandQueue()」関数
GPUに計算命令を送るのに必要。
9.カーネルを実行する。(計算命令を、キュー(順番待ちの列)に入れる。順番が来ると勝手に実行される。)
……「clEnqueueNDRangeKernel()」関数
10.GPU上のメモリをコピーして、計算結果を取得する。
……「clEnqueueReadBuffer()」関数
11.リソースの解放。(実際には、使用しなくなったリソースは順次開放してよい。)
……「clReleaseCommandQueue()」関数
……「clReleaseMemObject()」関数
……「clReleaseKernel()」関数
……「clReleaseProgram()」関数
……「clReleaseContext()」関数
……「free()」関数(これは自分で確保したメモリ空間。)
一応取得した順番と逆順に解放して行くが、そうする必要性は無い。
実際のコードは次の項目(OpenCLによるGPGPU入門②)を参照の事。
ところで……
実は
「1.プラットフォームのIDを取得する。」
「2.デバイスのIDを取得する。」
辺りの処理は、今回(OpenCLによるGPGPU入門②では)決め打ちで書いていますが、
それは、
OpenCLによるGPGPU入門①_2
で示しているように、事前に自分の環境情報を取得しているからです……。
0 件のコメント:
コメントを投稿