SSブログ

OS XのOpenCL - その22 [OS XのOpenCL]

前回はOpenCLが前提にしているハードウェアってどんなものか、というのを自分なりに調べた。そういうハードウェアにOpenCL独特の抽象化と機能付加のための概念が追加されてOpenCLとして動作することになる。こんどはプログラミングガイドにはOpenCL独特の言葉が出てきて、なんとなくスルーして読んでいたけど、これもちゃんと意味を自分なりに調べることにする。

15.2  言葉の整理

ということで、ガイドに出てきた言葉の整理をしてみる。このガイドはTerminologyがなくて、定義されないまま使われている言葉がある。部分的には「OpenCL on OS X basics」にあるけど、読んで理解したレベルでまとめてみる。

15.2.1  Device デバイス

GPUを抽象化したもの。OpenCLを実際に実行するためには、アクセス可能なGPUを調べて、複数のGPU(や、あるいはCPU)からひとつのデバイスを選択する必要がある。

15.2.2  Work Item ワークアイテム

抽象的な概念らしくて、正確にはよくわからない。ガイドには
      A work item is a parallel execution of a kernel on some data.
     It is analogous to a thread.
     Each kernel is executed upon hundreds of thousands of work items.
というような説明になっている。デバイス上にあるひとつの計算エレメントに対応する実行環境ことだろうと思われる。CPUで言えば、コアごとに動作するようになっているスレッドプールの、そのひとつのスレッドようなものだと言っているのであろう。

15.2.3  Host ホスト

GPUが接続されているCPUで動作する実行環境。ホストでmallocを実行するとそのCPUに接続されたメモリの領域が確保されて、GPUにその内容が転送できたり、GPUの計算結果をコピーできたりする。メモリはGPUと共有されている場合もある。OpenCLを使う側のプログラムはホスト上のアプリとして実行される。

15.2.4  Kernel カーネル

ワークアイテム上で動作するコード。Cに似た記述ができる。カーネルはvoid型を返すCの関数の形で書いて、GPUで実行できるようにXcode上でコンパイルされる。ガイドではカーネルはクラスオブジェクトとみなされているような記述もあって、ワークアイテムはカーネルのインスタンスであるというふうな記述もある。

ワークアイテムはカーネルを複数並列に実行する。実際にいくつ並列実行されるかはハードウェアによる。

15.2.5  Global ID グローバルID

デバイスにはワークアイテムが複数個存在できる。ワークアイテムにはインデクスが振られていてそれをグローバルIDという。グローバルIDはハード的にはリニアなインデクスだと思われるが、1次元だけでなく、2次元、3次元に構成することができる。それはホストとカーネルとでコンシステントであればよくて、ハードウェアがどうなっているかを知る必要はない。

15.2.6  OpenCL Memory OpenCLメモリ、Device Memory デバイスメモリ

カーネルがアクセスするメモリ。専用のメモリ領域確保関数を使って確保できる。ホストのメモリの内容とは相互にコピーできる。デバイスメモリは階層化されている。CPUで言えばキャッシュの階層のようなものだと思われる。CPUコアごとにL1キャッシュがあって、コア全体からアクセスできるL2キャッシュとバスに接続されたL3キャッシュがあるが、それと同じような階層があるらしい。

使い終わったらホストと同様に専用の関数を使って解放しなければならない。

15.2.7  Work Group ワークグループ

これも難しい。ワークアイテムは複数まとめてグループになっている。これはハードウェアのメモリ階層に対応しているらしい。同じワークグループに属しているワークアイテムは一部のメモリを共有している。

15.2.8  メモリ階層

OpenCLが前提にしているハードウェアモデルはでメモリ階層が3つある。
  1. プライベートメモリ。ワークアイテムごとに存在する。カーネルコードの中に自動変数をとると、それはプライベートメモリに確保されるようである
  2. ローカルメモリ。ワークグループごとにあってプライベートメモリはその一部のキャッシュのようなものらしい
  3. グローバルメモリ。ホストとやりとりできるメモリ。ローカルメモリはそのキャッシュのようなものらしい
ただし、CPUのキャッシュのようにオンデマンド(必要なアドレスのデータが呼ばれた時点で読みだしてキャッシュに格納する)ではなく、あらかじめ決定されているようである。しかし決定するためにはどのワークアイテムがどこをアクセスするかがわかってないと決められないので、カーネルがなにをするかわからないといけない。どの時点でどういうアルゴリズムで決定されるのかよくわからない。また動的、適応的なものかそれともハードウェアで決まってしまっているのかもよくわからない。なんだかすごく難しい話のような気がする。

それと、スタックのようなメモリ構造はどうするのかよくわからない。カーネル関数を入れ子にすることはできるのでスタックは必要だろうけど、ワークアイテムごとにスタックを持つのは大変だろうから、プライベートメモリでシミュレートする、とかなのかもしれない。よくわからない。

またOpenCLでは、実際にハードウェアがこういう構成でなくてもこのモデルに集約させるようである。例えば、CPUではこういったメモリ階層はすべて無視される。というのは、実際にはCPUにもメモリ階層があるけどOSによってプログラマからは隠蔽されているからである。ホストプログラミングのようにOSが隠蔽すればいいのではないか、と思うけどGPUではそういったオーバーヘッドが大きな不利益をもたらす場合があるのと、GPUに専用のOSがあるわけではないということだろう。

15.2.9  Compute Unit 計算ユニット、Processing (Computing) Element計算レメント

この使い分けはガイドで混乱しているように思えるが、単にタイプミスかもしれない。計算ユニットというのは一つのローカルメモリに接続する部分で、計算エレメントはその中の実際にワークアイテムが実行される部分のようである。
nice!(0)  コメント(0)  トラックバック(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。