OpenCLのお勉強
なんとなくOpenCLあたりを勉強しておけば役に立つかなぁと思い少しづつまとめるかも
OpenCLってなんなの?
CPUだったりGPUだったりDSPだったりの、アクセラレータの混在したヘテロジニアス(Heterogeneous)な環境向けの並列プログラミング環境。
一応ベンダーなりマシンに非依存なポータブルなコードが書ける。ベースとなる言語はC99。ただしホスト(CPU)側はなんでもいい。(APIを呼べるのならば)
どんなかんじに動作するの?
ひとつのホストに一つ以上のOpenCLデバイス(以下単にデバイス)が接続されていて、そのホスト(CPU)が計算するデータとプログラム(カーネル)を流しこんでいく。
カーネル(kernel)はデバイス上で実行されるコードの基本単位で関数のようなもの。そのカーネルをキューに送ると、適切な順にデバイスに割り当ててくれる。アウトオブオーダー実行もあるみたい。
デバイス上のプログラムには次の実行単位がある
- ワークアイテム work-item
- ワークグループ workgroup
work-itemは一番の基本単位。この単位でカーネルは動作している。これの動作している個数をGlobal dimensionsという。
workgroupはwork-itemの集まり。この単位でwork-itemは同期したり、共有メモリを持っている。ひとつのworkgroup中のwork-itemの個数をLocal dimensionsという。
work-itemはひとつひとつ独立して動作しており、他のwork-itemに依存した動作を行うと正しく動かないことがある。
OpenCLのメモリモデル
OpenCL上のメモリは階層化がなされておりアクセスの高速な順に次の種類がある。
- プライベートメモリ (Private Memory)
- ローカルメモリ (Local Memory)
- コンスタントメモリ (Constant Memory)
- グローバルメモリ (Global Memory)
- ホストメモリ (Host Memory)
プライベートメモリはwork-itemがそれぞれ独自に持つメモリで、主にレジスタに割り当てられる。
ローカルメモリはworkgroup内のwork-itemで共有されるメモリ領域。
コンスタントメモリは主に、カーネルの実行中に変更されないようなデータが置かれる領域。実体はグローバルメモリに置かれるが、定数用のキャッシュ領域がある場合にはそこにも置かれる。
グローバルメモリはデバイス自身が持つメモリ領域。カーネルからアクセスできる中では一番遅い。