13

こんにちは: グローバル ワーク サイズ (ディメンション) は、OpenCL のワーク グループ サイズ (ディメンション) の倍数である必要がありますか?

もしそうなら、作業グループの次元の倍数ではなく、マトリックスを処理する標準的な方法はありますか? 次の 2 つの可能性が考えられます。

作業グループ ディメンションのサイズをグローバル作業ディメンションの係数に動的に設定します。(これにより、要素を見つけるオーバーヘッドが発生し、ワーク グループが最適でないサイズに設定される可能性があります。)

グローバル作業の次元を作業グループの次元の最も近い倍数に増やし、すべての入力および出力バッファーを同じに保ちますが、セグメンテーション違反を回避するためにカーネルの境界をチェックします。つまり、目的の出力の境界外の作業項目に対しては何もしません。 . (これはより良い方法のようです。)

2番目の方法は機能しますか?より良い方法はありますか?(または、作業グループのディメンションはグローバルな作業ディメンションを分割する必要がないため、必要ないのでしょうか?)

ありがとう!

4

3 に答える 3

7

リンクチャドのThx。しかし、実際に読み進めると、次のようになります。

local_work_size が指定されている場合、global_work_size[0]、… global_work_size[work_dim - 1] で指定された値は、local_work_size[0]、… local_work_size[work_dim - 1] で指定された対応する値で割り切れる必要があります。

はい、ローカル作業サイズはグローバル作業サイズの倍数でなければなりません。

また、グローバル作業サイズを最も近い倍数に割り当て、境界に注意することもうまくいくと思います。試してみたらコメントを投稿します。

于 2010-07-02T10:53:41.383 に答える
4

これは古い投稿のようですが、いくつかの新しい情報でこの投稿を更新させてください。うまくいけば、それは他の誰かを助けることができます.

グローバル ワーク サイズ (ディメンション) は、OpenCL のワーク グループ サイズ (ディメンション) の倍数である必要がありますか?

回答: OpenCL 2.0 までは当てはまります。CL2.0 より前では、グローバル ワーク サイズはローカル ワーク サイズの倍数でなければなりません。そうしないと、clEnqueueNDRangeKernel を実行したときにエラー メッセージが表示されます。

しかしCL2.0からは不要になりました。アプリケーションのサイズに適合する任意のグローバル作業サイズを使用できます。ただし、ハードウェアの実装は依然として「古い」方法を使用している可能性があることに注意してください。これは、グローバル ワーク グループ サイズをパディングすることを意味します。したがって、パフォーマンスはハードウェア アーキテクチャに大きく依存します。異なるハードウェア/プラットフォームでは、まったく異なるパフォーマンスが表示される場合があります。さらに、バージョン 1.2 までの CL のみをサポートする古いプラットフォームをサポートするために、アプリケーションの互換性を取り戻したいと考えています。したがって、CL2.0 で追加されたこの新機能は、プログラミングを簡単にするためのものであり、制御可能なパフォーマンスと下位互換性を向上させるためのものだと思います。あなたが言及した次の方法を引き続き使用することをお勧めします。

グローバル作業の次元を作業グループの次元の最も近い倍数に増やし、すべての入力および出力バッファーを同じに保ちますが、セグメンテーション違反を回避するためにカーネルの境界をチェックします。つまり、目的の出力の境界外の作業項目に対しては何もしません。 . (これはより良い方法のようです。)

回答:あなたは絶対に正しいです。これは、そのような場合を処理する正しい方法です。ローカル ワーク グループのサイズは慎重に設計してください (レジスタの使用状況、キャッシュ ヒット/ミス、メモリ アクセス パターンなどの要因を考慮してください)。次に、グローバル作業サイズをローカル作業サイズの倍数にパディングします。それでは、準備完了です。

考慮すべきもう 1 つの点は、カーネルで非常に多くの境界チェック作業がある場合、バッファの代わりにイメージ オブジェクトを利用してデータを格納できることです。画像の場合、境界チェックはハードウェアによって自動的に行われ、ほとんどの実装でオーバーヘッドはほとんどありません。したがって、グローバルな作業サイズをパディングし、データを画像オブジェクトに保存してから、境界チェックを気にせずに通常どおりコードを記述するだけで済みます。

于 2016-04-13T20:53:35.053 に答える
1

基準によれば、私が見たものである必要はありません。ブランチで処理すると思いますが、どのような行列演算を行っているのか正確にはわかりません。

http://www.khronos.org/registry/cl/specs/opencl-1.1.pdf#page=131

global_work_sizeカーネル関数を実行する次元work_dimのグローバル作業項目の数を記述する符号なし値の配列を指します。work_dimグローバル ワークアイテムの総数はglobal_work_size[0]* ... *として計算されますglobal_work_size[work_dim – 1]

で指定された global_work_size値 + で指定された対応する値は、カーネルの実行がキューに入れられるデバイスに対して指定さglobal_work_offset れた範囲を超えることはできません 。sizeof(size_t)デバイスのは、表 4.3sizeof(size_t)を使用して決定できます 。CL_DEVICE_ADDRESS_BITSたとえば、 CL_DEVICE_ADDRESS_BITS= 32 の場合、つまりデバイスが 32 ビットのアドレス空間を使用している場合、size_tは 32 ビットの符号なし整数であり、global_work_size値は 1 .. 2^32 - 1 の範囲内である必要があります。この範囲外の値は CL_OUT_OF_RESOURCESエラーを返します。

于 2010-07-01T06:51:05.250 に答える