0

グリッド内のアイテムを処理しています。アイテムのタイプに応じて、異なるタイプの計算/関数を実行する必要があります。しかし、同じことをしている作業項目間で分岐を行うのは非常に悪いことだと読んだことがあります。これを回避するために、グリッドをタイプごとにグリッドに分割できます (この特定のケースでは 2 つしか必要ありません)...

この場合、何が良いでしょうか。そこに分岐を残すか、2 つのグリッドをタイプごとに 1 つずつ作成しますか? これは、ブランチ内で何が起こるか (計算限界) とグリッドの大きさ (メモリ/レイテンシー限界) に依存することを理解しています。

これらの種類の決定に従うべきいくつかの基本ルールはありますか、それとも一般的にどちらが優れているかについてのコンセンサスはありますか?

編集: (空間) グリッドは、通常の空間グリッドのようにまばらではありませんが、最大約 500.000 の要素を保持する構造体 (構造体あたり約 200 バイト) の密な配列 (空の要素なし) です。

この配列を別のソースから入力し、そのソースを使用して三角形または線分を配置します。

次に、このグリッドを使用して、線分/線分または線分/三角形の衝突検出を行う必要があります。したがって、問題は、この場合、2 つの別個の配列 (引数のために 250.000 要素 x 200 バイトとします) を埋めて、ワークアイテムに線/線または線/三角形のみのバッチ計算を実行させる方が効率的かどうかです.. 500.000x200 バイトの大きなものを 1 つ作成し、各ワークアイテムに特定のタイプで実行する計算を決定させます。

4

2 に答える 2

1

これには一般的なルールはなく、場合によって異なります。多くのコードを分岐する場合は、メモリを再配置する方が明らかに優れています。ただし、分岐が 2 つの命令だけの場合は、メモリを再形成しないでください。

まず、各タイプ (CPU 側または単純なカーネル) のアイテムの数を分類し、アイテムのタイプごとに特定のカーネルを実行します。ただし、これはあなたのケースには適していない場合があります。

コードを投稿していただければ、正しい方向に導くことができるかもしれません。

于 2013-11-06T14:57:51.393 に答える
1

それは、新しいグリッドの構造と古いグリッドの構造によって異なります。

最悪のケースを考えてみましょう。通常の長方形のグリッド (画像のような) すべての奇数アイテムがタイプ 1 で、すべての偶数アイテムがタイプ 2 の場合、基本的にスレッドの半分が GPU でアイドル状態になります (タイプ 1 がカウントされている間、タイプ 2 スレッドは「アイドル」です)。これは、ワークグループ内のアイテムが通常、プログラム カウンターを共有しているためです。

新しいグリッドが 2 つのカーネル呼び出しであり、単純な「type2 ではない? return」である場合、最初のケースよりも悪化します。ただし、すべての項目が正しいタイプである 2 つのグリッドを作成できた場合は、それを分割する方がはるかに優れています。

元のグリッドが正確に 2 つの半分の画像である場合、おそらく問題にはなりません。境界内のグループのみが余分な作業を実行します。

枝はそれほど悪いものではありません。ブランチがあり、ワークグループ内の単一のスレッド (または HW でのスケジューリングの単位は何でも) が他のスレッドとは異なる方向に進むときはいつでも、両方のブランチのすべてのコードがどこでも使用されるように考えてください。

これは、特別な条件が適用される場合に高価な計算を実行しないなどの最適化が一般に GPU で機能しない理由でもあります。他のスレッドが条件を満たさない場合でも、すべてのスレッドで効果的に計算するからです。

于 2013-11-06T15:07:45.410 に答える