GPUでの比較がなぜそれほど高価なのですか?


10

衝突検出クラスのパフォーマンスを向上させようとしているときに、gpuで費やされた時間の約80%がループするバケットの境界を把握しようとするif / else条件に費やされたことがわかりました。

より正確に:

  1. 各スレッドはIDを取得し、そのIDによってメモリから三角形(それぞれ3つの整数)をフェッチし、それらの3つによって頂点をフェッチします(それぞれ3つの浮動小数点数)。

  2. 次に、頂点を整数グリッドポイント(現在は8x8x8)に変換し、それらをそのグリッドの三角形の境界に変換します。

  3. 3つのポイントを境界に変換するために、各ポイント間で各次元の最小/最大を見つけます

私が使用しているプログラミング言語にはminmax組み込み関数がないため、次のように自分で作成しました。

procedure MinMax(a, b, c):
   local min, max

   if a > b:
      max = a
      min = b
   else:
      max = b
      min = a
   if c > max:
      max = c
   else:
      if c < min:
         min = c

   return (min, max)

したがって、平均すると2.5 * 3 * 3 = 22.5の比較になるはずです。これは、実際の三角形よりもずっと多くの時間を消費することになります-エッジ交差テスト(約100 * 11-50命令)。

実際、私はCPUで必要なバケットを事前計算し(シングルスレッド、ベクトル化なし)、バケット定義と一緒にそれらをGPUビューに積み重ねて、GPUにスレッドごとに4回以上の追加の読み取りを行わせると、試行より6倍高速であることがわかりましたその場で境界を把握する。(動的メッシュを扱っているため、実行する前に再計算されることに注意してください)

では、なぜGPUでの比較がひどく遅いのでしょうか。


2
あなたの質問は、特定のタイプのハードウェアにおける特定のコードの命令レベルのパフォーマンスに関するものです。私には、コンピューターサイエンスの質問というより、プログラミングの質問のように思えます。
David Richerby、2015

7
私の推測では、高価なのは比較ではなく分岐です。コンパイラがプレディケーションを使用しない場合(またはGPUがプレディケーションを提供しない場合)、ブランチが使用され、「スレッド」フォークが発生します(GPUはSIMD指向であるため)。条件をマスクに変換し、マスクを使用して条件付きの移動/スワップを合成することは、合理的な代替手段になる場合があります。
Paul A. Clayton

1
@DavidRicherby私はそれが特定のものかどうかはわかりません。この質問はどのSIMDアーキテクチャにも当てはまりませんか?
kasperd

1
@DavidRicherby:CS部門でコンプアーチを教える理由は、コンプアーチが選択したアルゴリズムに影響を与えるためです。SIMDアーキテクチャは、ネストされたブランチのないプログラムの記述方法を理解できる場合にのみ、高いスループットを生成できます。
Wandering Logic

2
Wandering Logicの答えはそれほど明白ではないように述べているので、GPUは、多くの「スレッド」が同時に同じ命令にあると想定することで機能します。したがって、GPUは大まかに言えば、真のブランチだけでなく、すべてのブランチを取ります。これが、GPUが隣人が通常同じ分岐を取るという事実を利用する理由です。これが真実でない場合、パフォーマンスはひどいです。
ロブ

回答:


10

GPUはSIMDアーキテクチャです。SIMDアーキテクチャでは、処理するすべての要素に対してすべての命令を実行する必要があります。(このルールには例外がありますが、ほとんど役に立ちません)。

したがって、MinMaxルーチンでは、すべての呼び出しで3つの分岐命令すべてをフェッチする必要があるだけでなく(平均して2.5しか評価されない場合でも)、すべての代入ステートメントもサイクルを消費します(実際に「実行」されない場合でも) )。

この問題は、スレッドの相違と呼ばれることもあります。マシンに32個のSIMD実行レーンがある場合でも、フェッチユニットは1つだけです。(ここで、「スレッド」という用語は基本的に「SIMD実行レーン」を意味します。)したがって、内部的に各SIMD実行レーンは「有効/無効」ビットを持ち、ブランチは実際にはそのビットを操作するだけです。(例外は、すべてのSIMDレーンが無効になる時点で、フェッチユニットは通常、「else」句に直接ジャンプします。)

したがって、コードでは、すべてのSIMD実行レーンが次のことを実行しています。

compare (a > b)
assign (max = a if a>b)
assign (min = b if a>b)
assign (max = b if not(a>b))
assign (min = a if not(a>b))
compare (c > max)
assign (max = c if c>max)
compare (c < min if not(c>max))
assign (min = c if not(c>max) and c<min)

一部のGPUでは、条件式から述語への変換が、GPUがそれ自体を実行している場合は遅くなる場合があります。@ PaulA.Claytonで指摘されているように、プログラミング言語とアーキテクチャに述語付きの条件付き移動操作(特にの形式の1つif (c) x = y else x = z)がある場合は、より適切に実行できる可能性があります。(しかし、おそらくあまり良くありません)。

また、配置c < min条件内部elseのことはc > max不要です。それは確かにあなたに何も保存していません、そして(GPUがそれを自動的に予測に変換しなければならないことを前提として)実際にそれを2つの異なる条件にネストさせることは害を及ぼすかもしれません。


2
(これの一部が不明確な場合は申し訳ありませんが、理論家が問題をトピックから外れる前に回答を得ようとしています。)
Wandering Logic


一部のアルゴリズムは、SIMD並列処理によって高速化できないという意味でトピックに当てはまります。(例:理由のより理論的な扱いについては、Work、Spanなど)
Rob

1
ここに、分岐の基本に関する別の講義があります。people.maths.ox.ac.uk/ gilesm / cuda / lecs / lec3-2x2.pdfこれらから、(Nvidiaでの)問題はワープごとのみであることに注意してください。異なるワープで実行されているコードは、うまく分岐する場合があります。それを回避する方法を提案する別の論文:hal.inria.fr/file/index/docid/649650/filename/sbiswi.pdf
Fizz

少し異なるタックについてですが、eprint.iacr.org / 2012 / 137.pdfの質問の下に書いたコメントと同様に、予測されるパフォーマンスと比較して10倍のスローダウンはGPUにとって「正常」である可能性があります(通常は公式にサポートされていないツールを使用して)そのアセンブリに。GPUターゲティングコンパイラが改善された可能性はありますが、私は息を止めません。
Fizz、2015
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.