衝突検出クラスのパフォーマンスを向上させようとしているときに、gpuで費やされた時間の約80%がループするバケットの境界を把握しようとするif / else条件に費やされたことがわかりました。
より正確に:
各スレッドはIDを取得し、そのIDによってメモリから三角形(それぞれ3つの整数)をフェッチし、それらの3つによって頂点をフェッチします(それぞれ3つの浮動小数点数)。
次に、頂点を整数グリッドポイント(現在は8x8x8)に変換し、それらをそのグリッドの三角形の境界に変換します。
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での比較がひどく遅いのでしょうか。