3

私は現在、かなりハリー マッチング追跡アルゴリズム (より大きな画像処理アルゴリズムの一部) を OpenCL に移行しています。

このアルゴリズムは、処理のためにいくつかの内部行列とベクトルを使用します。それらの半分はかなり小さいサイズ (10 列未満) ですが、残りの半分は入力行列 (n * n、2n * n など) によってはかなり大きくなる可能性があります。

すべての内部行列の定義は、入力行列に依存します。

標準にはローカル割り当て機能がないため、メモリのチャンクをグローバル メモリからワークアイテムのプライベート メモリにマッピングすることで、メモリの問題に取り組みました。コンテキストのセットアップ中にチャンクが重複しないようにして、実行時にデータの一貫性が保証されるようにします。

このアプローチは私には適切ではありません。ハックのように感じます。

このような状況に遭遇した人はいますか?あなたの解決策は何ですか?

4

2 に答える 2

2

このようなグローバル メモリ バッファのセグメント化は問題ありませんが、通常はホストへの出力にのみ使用されます。通常、グローバル メモリ アクセスには数百命令サイクルのコストがかかるため、次のことをお勧めします。

  1. 代わりに、一時データを __private または __local メモリに割り当てます。後者については CL_DEVICE_LOCAL_MEM_SIZE を確認してください。これは通常 16KB ~ 64KB です。マルチプロセッサの __local メモリはワークグループ間で共有されることに注意してください。CL_DEVICE_LOCAL_MEM_SIZE の制限内であっても、使用量が多すぎると、マルチプロセッサの占有率に悪影響を及ぼし、したがってスループットに悪影響を及ぼします。これを観察する最善の方法は、ワークロードとデバイスで実験することです。

  2. 一時行列が __local メモリに対して大きすぎる場合は、各作業項目を小さくして、収まるようにし、グローバル メモリのかなりのオーバーヘッドを回避できるかどうかを検討してください。

  3. 各ワークアイテムの最小データフットプリントに厳しい制約がある場合は、説明したように __global メモリを使用してください。ただし、次のことを確認してください。

    • 多数のワークグループを使用してカーネルを起動し、一部がグローバル メモリ アクセスを待機している間、他のグループをマルチプロセッサでスケジュールできるようにします (「レイテンシの隠蔽」)。
    • ベンダーがこれをサポートしている限り、グローバル メモリ アクセスを結合します。NVidia OpenCL のベスト プラクティス ガイドには詳細が記載されており、100% を超えるパフォーマンスの向上は非常に達成可能です。
于 2012-11-08T16:56:46.380 に答える
1

あなたのアプローチは問題ないようです。

NVidias OpenCL のベスト プラクティス ガイドをご覧ください。セクション 3.2.2 - 「共有メモリ」には、行列乗算の例があります。各ワーキング グループは、必要なデータをグローバル メモリからローカル メモリにコピーします。

于 2012-11-07T21:51:25.417 に答える