OS XのOpenCL - その4 [OS XのOpenCL]
脱線の続き。OS XでのOpenCLを知るためのAppleのガイドの抄訳。今日は基本のまとめ。ここがガイドのさわりらしい。ここが理解できればあと読む必要はないんだろうけど、ふつうわからん。とりあえず読む。
もしソースを文字列としてファイルから読み込んでランタイム時点でOpenCLプログラムを作る必要があるなら、あるいはAPIレベルでキューを制御したいなら、クロノスグループから提供されているOpenCLの規格を参照せよ。
MacはつねにひとつのCPUを持っている。GPUをひとつも持っていなかったり、複数持っていたりする。MacのCPUは複数の計算ユニットを持っている。マルチコアCPUと呼ばれる。CPUの計算ユニットの数が同時に実行できるワークグループの数を制限する。
CPUはふつう2から8個の計算ユニットを持っていて、ときにはもっとある。グラフィクスプロセシングユニット(GPU)はふつうはたくさんの計算ユニットを持っている。現在のMacのGPUは計算ユニットを何十も持っていることを特徴にしている。未来のGPUでは数百になる。OpenCLにとっては計算ユニットの数は無関係である。OpenCLはCPUは8個、GPUは100個がひとつのデバイスにあると見なしている。
OpenCL APIのOS X10.7での実装はCPUとGPUの両方のデバイスで、データ並列プログラムを設計してコーディングするのを助ける。データ並列プログラムでは同じプログラム(あるいはカーネル)が異なる部分のデータに対して並列的に動作する。それぞれの処理はワークアイテム(work item)と呼ばれワークアイテムIDがわり与えられる。ワークアイテムIDは3次元まで使われる(N-Dレンジと呼ばれる)。
カーネルは本質的にOpenCL言語で書かれた関数である。それはOpenCLをサポートするすべてのデバイスで実行できるようにコンパイルされる。しかしカーネルは他のプログラムング言語から呼ばれる関数とは違っている。それはカーネルを呼び出すとき、実際に起こっていることは、たくさんのカーネルのインスタンスが実行されてそれぞれが異なるひとかたまりのデータを処理しているのである。
OpenCL関数を呼び出すプログラムはカーネルが実行されるコンテクストをセットアップし、実行のためにカーネルを待ち行列に投入する。そのようなプログラムはホストアプリとして知られている。ホストアプリはCPU上でOS Xによって実行される。ホストアプリが実行されるデバイスをホストデバイスという。カーネルを実行する前にホストアプリは
ホストアプリはメモリオブジェクトを読み書きするコマンドを待ち行列に投入する。そのメモリオブジェクトはカーネルからもアクセス可能なものである。「OS X OpenCLのメモリオブジェクト」参照。メモリオブジェクトはデバイスメモリを操作するために使われる。OpenCLで使われるメモリオブジェクトにはふたつのタイプがある。バッファオブジェクトとイメージオブジェクトである。バッファオブジェクトはどんな型のデータでも保持できる。イメージオブジェクトは与えられたフォーマットのピクセルの形に整形されている。
C、C++、Objective-Cで書かれたホストアプリによってカーネルは実行のために待ち行列に投入される。カーネルはそれが実行されるデバイスにカスタマイズされてコンパイルされていなければならない。OpcnCLカーネルのソースコードは別のファイルかホストアプリのソースコードの中にインラインで含むことができる。
OpenCLカーネルは以下のようにコンパイルできる。
ワークグループはひとまとまりのワークアイテムで、並列的に手分けしたデータを実行する。それぞれのワークグループは一つの計算ユニットで実行される。
ワークグループ次元(Workgroup dimensions)はカーネルがどのように並列的に入力を操作するかを決定する。アプリは普通入力のサイズに基づいて次元を決める。いくつか制約がある。例えばあるカーネルがあるデバイスの上で起動されるワークアイテムの最大数がある。
3 OS XでのOpenCLの基本
OS Xに供給されたツールでOpenCLのカーネルをXcodeプロジェクトのリソースとして含めることができ、アプリの他の部分と一緒にコンパイルでき、普通の関数と同じように引数を渡してカーネルを呼ぶことができ、CPUとGPUの上でOpenCLコマンドとカーネルを実行するキューとしてGCDを使うことができる。もしソースを文字列としてファイルから読み込んでランタイム時点でOpenCLプログラムを作る必要があるなら、あるいはAPIレベルでキューを制御したいなら、クロノスグループから提供されているOpenCLの規格を参照せよ。
3.1 コンセプト
OpenCLの規格では計算用プロセッサをデバイスと呼ぶ。OpenCLデバイスはひとつまたは複数の計算ユニットを持つ。ワークグループは一つの計算ユニットを実行する。計算ユニットはひとつまたは複数のプロセシングエレメントとローカルメモリを持つ。MacはつねにひとつのCPUを持っている。GPUをひとつも持っていなかったり、複数持っていたりする。MacのCPUは複数の計算ユニットを持っている。マルチコアCPUと呼ばれる。CPUの計算ユニットの数が同時に実行できるワークグループの数を制限する。
CPUはふつう2から8個の計算ユニットを持っていて、ときにはもっとある。グラフィクスプロセシングユニット(GPU)はふつうはたくさんの計算ユニットを持っている。現在のMacのGPUは計算ユニットを何十も持っていることを特徴にしている。未来のGPUでは数百になる。OpenCLにとっては計算ユニットの数は無関係である。OpenCLはCPUは8個、GPUは100個がひとつのデバイスにあると見なしている。
OpenCL APIのOS X10.7での実装はCPUとGPUの両方のデバイスで、データ並列プログラムを設計してコーディングするのを助ける。データ並列プログラムでは同じプログラム(あるいはカーネル)が異なる部分のデータに対して並列的に動作する。それぞれの処理はワークアイテム(work item)と呼ばれワークアイテムIDがわり与えられる。ワークアイテムIDは3次元まで使われる(N-Dレンジと呼ばれる)。
カーネルは本質的にOpenCL言語で書かれた関数である。それはOpenCLをサポートするすべてのデバイスで実行できるようにコンパイルされる。しかしカーネルは他のプログラムング言語から呼ばれる関数とは違っている。それはカーネルを呼び出すとき、実際に起こっていることは、たくさんのカーネルのインスタンスが実行されてそれぞれが異なるひとかたまりのデータを処理しているのである。
OpenCL関数を呼び出すプログラムはカーネルが実行されるコンテクストをセットアップし、実行のためにカーネルを待ち行列に投入する。そのようなプログラムはホストアプリとして知られている。ホストアプリはCPU上でOS Xによって実行される。ホストアプリが実行されるデバイスをホストデバイスという。カーネルを実行する前にホストアプリは
- 必要なら、計算デバイスが利用可能かどうか調べる
- アプリにふさわしい計算デバイスを選択する
- 選択された計算デバイス用にディスパッチキューを作る
- カーネルが実行するためのメモリオブジェクトをアロケートする(このステップは簡便さのため、もっと早く行われることがある)
ホストアプリはメモリオブジェクトを読み書きするコマンドを待ち行列に投入する。そのメモリオブジェクトはカーネルからもアクセス可能なものである。「OS X OpenCLのメモリオブジェクト」参照。メモリオブジェクトはデバイスメモリを操作するために使われる。OpenCLで使われるメモリオブジェクトにはふたつのタイプがある。バッファオブジェクトとイメージオブジェクトである。バッファオブジェクトはどんな型のデータでも保持できる。イメージオブジェクトは与えられたフォーマットのピクセルの形に整形されている。
C、C++、Objective-Cで書かれたホストアプリによってカーネルは実行のために待ち行列に投入される。カーネルはそれが実行されるデバイスにカスタマイズされてコンパイルされていなければならない。OpcnCLカーネルのソースコードは別のファイルかホストアプリのソースコードの中にインラインで含むことができる。
OpenCLカーネルは以下のようにコンパイルできる。
- コンパイル時点で一緒にコンパイルされ、ホストアプリによって投入されるときに実行される
- ホストアプリによって投入されるときにコンパイルされそのあと実行される
- 前もってコンパイルされたバイナリを実行する
ワークグループはひとまとまりのワークアイテムで、並列的に手分けしたデータを実行する。それぞれのワークグループは一つの計算ユニットで実行される。
ワークグループ次元(Workgroup dimensions)はカーネルがどのように並列的に入力を操作するかを決定する。アプリは普通入力のサイズに基づいて次元を決める。いくつか制約がある。例えばあるカーネルがあるデバイスの上で起動されるワークアイテムの最大数がある。
3.2 必要な開発タスク
OS X10.7時点で、OpenCL開発プロセスは次の主なステップを含んでいる。- 並列化すべきタスクを同定する。
どうやって効率的に並列化するかを決めることは、OpenCLプログラムを開発する上で最も難しい部分となることがある。「並列化可能なルーチンの同定」参照。 - カーネル関数を書く
「OS XのOpenCLでどのようにカーネルはデータを扱うか」参照。
「基礎的なカーネルコードのサンプル」にはXcodeを使ってカーネルコードをファイルに保存してコンパイルするかを示している。 - カーネルを呼び出すホストコードを書く
- GCDで待ち行列にカーネルを投入するには「OpenCLにGCDを使う」参照
- カーネルに引数を渡したり結果を回収するには「OS X OpenCLメモリオブジェクト」参照
- OpenCLのホストがOpenGLアプリとデータを共有するには「OpenCLとOpenGL間でのデータ共有」参照
- GCDを使ってOpenCLホストがOpenGLアプリと同期を取るには「GCDでのOpenCLOpenGL相互運用」参照
- OpenCLホストがIOSurfaceを使ってカーネルとデータをやり取りするには「OpenCLでIOSurfaceを使う」参照
- Xcodeを使ってホストコードをファイルに保存してコンパイルするには「基礎的なホストコードのサンプル」参照
- Xcodeでコンパイルする
- 実行する
- (必要なら)デバグする
- (必要なら)パフォーマンスを改善する
- カーネルがCPUで実行されるなら、「オートベクトライザ」参照、その他の最適化には「CPUでのパフォーマンス改善」を参照
- GPUを使うなら「GPUでのパフォーマンス調整」参照
2015-04-23 21:14
nice!(0)
コメント(0)
トラックバック(0)
コメント 0