OpenCL:待っていました-nVidiaのバージョン1.1ですが、何が新しくなったのですか?

少しの歴史または約束された3年が待っています



1年ほど前、Khronos GroupはOpenCL 1.1の新しいバージョンを導入し、nVidiaはすぐに、新しい標準をサポートするプレリリースドライバーがすでにあることを自慢しました。 すべてがうまくいきますが、プレリリースのみが機能するツールではありません(ここと公式ドライバーでは十分なバグがありますが、テストバージョンではさらにそうです)。開発者は正直に新しいバージョンのリリースを待ちました。 CUDA 4が登場しましたが、OpenCLは存在せず、存在しませんでした。 さらに、OpenCLのプレリリースバージョンでさえ、新しいドライバーバージョンから除外されました。 CUDA 3 + OpenCL 1.1の古いドライバーか、CUDA 4 + OpenCL 1.0の新しいドライバーを選択する必要がありました。 しかし、今日それは起こりました! 開発者は、最終バージョンが公式の280.13ドライバーですでに利用可能であることを示す手紙を受け取りましたが、ベータ版はまだベータ版ですが、これは長くはかかりません。



そこで、新しいバージョンで何が新しくて良いのかを覚えて、この機能やその機能が必要になる理由や、知っておくべき落とし穴があるかどうかについてのコメントを共有することにしました。





OpenCL 1.1の新機能



Khronos Groupのリストを見てみましょう。そこにないものを思い出したら、それを追加します。



ホストスレッドの安全性


スレッドセーフは便利なものです。今は、何を呼び出すか、どのように同期するかを考える必要はありません。 1枚のカードが使用されている限り、それは適切な質問であり、特別な意味はありません。 多くのカードがあり、そのフローごとに、はい、人生は楽になります。

ここには、通常書かれていない例外が1つあります。clSetKernelArg関数は、同じカーネルオブジェクトに対して呼び出された場合、スレッドセーフではありません(健康のために、別のオブジェクトに呼び出します)。 速度のために(あまり意味がわかりません)、または異なるフローで1つのオブジェクトを使用する意味がないため、それを行いましたが、事実は事実なので、注意する必要があります。



サブバッファオブジェクト


実際、バッファをいくつかの断片に分割し、目的の断片を目的のデバイスに送信できます。 繰り返しますが、複数のグラフィックカードと移植性の向上の場合に役立ちます。 はい。各カードに個別のバッファを作成する必要がない場合、データの整合性が保持されます。 一般的には可能ですが、便利になります。

小さなニュアンス(完全に論理的):サブバッファーへの書き込みと、交差するサブバッファーまたはメインバッファーからの読み取りを同時に行うことはできません。その場合、結果は定義されません。



ユーザーイベント


ユーザーが独自のイベントを作成できるようにするclCreateUserEventおよびclSetUserEventStatusコマンドがあります。 以前は、OpenCLコマンドの実行後に発生したイベントにのみすべてをバインドすることが可能でした。 繰り返しますが、それなしでもできます(イベント後にキューに新しいコマンドを追加するだけです)が、より便利になりました。



イベントコールバック


clSetEventCallback関数が登場しました 。これは、イベントステータスがそれに応じて変化したときに呼び出されるユーザー定義関数を登録します。 複数のユーザー定義関数を追加できますが、それらが呼び出される順序は定義されていません。 数ミリ秒ごとにイベントのステータスを確認する前に、このアドオンがすでに好きでした。今ではすべてが便利になり、最も重要なことには、これらの数秒が保存され、プロセス全体が簡素化されます。 私にとって、このActionScriptは何か思い出させてくれます:)



ところで、別の便利な関数はclSetMemObjectDestructorCallbackです 。これにより、cl_memオブジェクトが削除されたときに呼び出されるカスタム関数を追加できます。



3成分ベクトル


以前はサイズが2、4、8、16のベクトルがありましたが、私たちはすべて3次元空間に住んでおり、3次元ベクトルは一般的なものです。 また、4次元を使用する場合、レジスタ全体がすでに失われているため、大きな無駄です。 もちろん、独自に作成することもできますが、OpenCLの組み込みの幾何学的関数では処理されません。 確かに怖いわけではなく、自分で書くこともできます(組み込み関数のハードウェアアクセラレーションがあるかどうかはまだ謎です。どうにかして確認する必要があります)が、ネイティブサポートの方がきれいです(私の場合はきれいです) =維持しやすい)は事実です。



カーネルがNDRangeの異なる部分で動作できるようにするグローバルワークオフセット


正直なところ、私はいつもそれが以前だと思っていました。 はい、両方のバージョンの公式ドキュメントに記載されています。 ここで何が変更されたかを知っている人は、登録を解除してください。



バッファオブジェクトの1D、2D、または3Dの長方形領域の読み取り、書き込み、コピー


関数clEnqueueReadBufferRect、clEnqueueWriteBufferRectおよびclEnqueueCopyBufferRectが登場しました 。これにより、バッファーの長方形の領域をコピーできます。 つまり 行列(画像と同じ行列)に行列ごとに行列または画像を保存し、その一部のみを取得する必要がある場合、バッファ全体の読み取り/コピー/書き込みや行ごとのコマンドの発行は不要になりますが、単純に行列とOpenCLパラメーターを指定できます自分ですべてを行います。 個人的には、これを行う必要はありませんでしたが、大規模なマトリックスに役立つはずです。



ミラーリングされたリピートアドレッシング


画像をテクスチャとして保存する場合、 CLK_ADDRESS_MIRRORED_REPEATを使用して、テクスチャの境界を越えたときに、その反射がそこにあるかのように結果を得ることができます。 そして、それはあなたが好きなだけ何度も動作し、反射は交互に見えるようです。



さまざまな追加および改善


clGetKernelWorkGroupInfo関数のCL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE引数は、このデバイスに適したグループサイズの乗数を提供する必要があります。 正しく理解すれば、このことはワープのサイズを返します(グループサイズには常にいくつかのワープ全体が含まれます)。これは、異なるプラットフォームでアプリケーションを自動調整するためのものです。 しかし、私はまだ試していないので、間違っている可能性があります。



clGetContextInfo関数のCL_CONTEXT_NUM_DEVICES引数は、コンテキストにあるデバイスの数を示します。



OpenCL のどのバージョンが使用されているかをプログラムで調べるのに役立つのは、マクロCL_VERSION_1_0およびCL_VERSION_1_1です。



次のような拡張機能も標準に導入されました。

cl_khr_byte_addressable_store

cl_khr_global_int32_base_atomics、

cl_khr_global_int32_extended_atomics、

cl_khr_local_int32_base_atomics、

cl_khr_local_int32_extended_atomics

また、組み込みのアトミック操作のプレフィックスatom_からatomic_に変更されました。



2つの新しい拡張機能があります。

cl_khr_gl_eventおよびcl_khr_d3d10_sharing



いくつかの新しいコマンドも登場しました。

get_global_offset、

ミンマグ

マックスマグ

async_work_group_strided_copy、

vec_step、

シャッフル

シャッフル2。



私はすべてのアップデートを説明しますが、私は眠りたいです、誰かがこのリストを役に立つと思うことを望みます。



PS:繰り返しますが、私の投稿にはコード行はありません。後で修正することをお約束します。例とテストについて多くのアイデアがありますが、今のところはそれなしで生きます:)



PS2: OpenCLの前回の投稿:汎用性と高いパフォーマンス、またはそれほど単純ではありませんか? 彼らはOpenCLについての本について尋ねたが、それから私は何も答えなかった。 それで、今日、 「OpenCL Programming Guide」という本がほんの一週間前に出版されたことを発見しました。 私はまだそれを読んでいませんが、簡単に見てみると、かなり面白いように見えます。



All Articles