これは古い投稿のようですが、いくつかの新しい情報でこの投稿を更新させてください。うまくいけば、それは他の誰かを助けることができます.
グローバル ワーク サイズ (ディメンション) は、OpenCL のワーク グループ サイズ (ディメンション) の倍数である必要がありますか?
回答: OpenCL 2.0 までは当てはまります。CL2.0 より前では、グローバル ワーク サイズはローカル ワーク サイズの倍数でなければなりません。そうしないと、clEnqueueNDRangeKernel を実行したときにエラー メッセージが表示されます。
しかしCL2.0からは不要になりました。アプリケーションのサイズに適合する任意のグローバル作業サイズを使用できます。ただし、ハードウェアの実装は依然として「古い」方法を使用している可能性があることに注意してください。これは、グローバル ワーク グループ サイズをパディングすることを意味します。したがって、パフォーマンスはハードウェア アーキテクチャに大きく依存します。異なるハードウェア/プラットフォームでは、まったく異なるパフォーマンスが表示される場合があります。さらに、バージョン 1.2 までの CL のみをサポートする古いプラットフォームをサポートするために、アプリケーションの互換性を取り戻したいと考えています。したがって、CL2.0 で追加されたこの新機能は、プログラミングを簡単にするためのものであり、制御可能なパフォーマンスと下位互換性を向上させるためのものだと思います。あなたが言及した次の方法を引き続き使用することをお勧めします。
グローバル作業の次元を作業グループの次元の最も近い倍数に増やし、すべての入力および出力バッファーを同じに保ちますが、セグメンテーション違反を回避するためにカーネルの境界をチェックします。つまり、目的の出力の境界外の作業項目に対しては何もしません。 . (これはより良い方法のようです。)
回答:あなたは絶対に正しいです。これは、そのような場合を処理する正しい方法です。ローカル ワーク グループのサイズは慎重に設計してください (レジスタの使用状況、キャッシュ ヒット/ミス、メモリ アクセス パターンなどの要因を考慮してください)。次に、グローバル作業サイズをローカル作業サイズの倍数にパディングします。それでは、準備完了です。
考慮すべきもう 1 つの点は、カーネルで非常に多くの境界チェック作業がある場合、バッファの代わりにイメージ オブジェクトを利用してデータを格納できることです。画像の場合、境界チェックはハードウェアによって自動的に行われ、ほとんどの実装でオーバーヘッドはほとんどありません。したがって、グローバルな作業サイズをパディングし、データを画像オブジェクトに保存してから、境界チェックを気にせずに通常どおりコードを記述するだけで済みます。