可変長ループがGPUシェーダーに与える影響


9

デモシーンなど、GPU内で手続き型コンテンツをレンダリングするのが一般的です(画面いっぱいに1つの四角形を描画し、GPUにピクセルを計算させる)。

レイマーチングが人気です:

ここに画像の説明を入力してください

これは、GPUがピクセルごとに不明な数のループ反復を実行していることを意味します(ただし、のような上限を設定できますmaxIterations)。

可変長ループがあると、シェーダーのパフォーマンスにどのような影響がありますか?

単純なレイマーチングの擬似コードを想像してみてください。

t = 0.f;
while(t < maxDist) {
    p = rayStart + rayDir * t;
    d = DistanceFunc(p);
    t += d;
    if(d < epsilon) {
       ... emit p
       return;
    }
}

さまざまな主流のGPUファミリ(Nvidia、ATI、PowerVR、Mali、Intelなど)はどのように影響を受けますか?頂点シェーダー、特にフラグメントシェーダー?

どのように最適化できますか?


残念ながら、この質問はここで適切に回答するには難しすぎます。既に与えられた1つの回答は、そのようなソースを参照する価値があることを示しています(動的分岐を含みます)。「トピック」の+1 ..
teodron、2012

1
@teodronは敗北者にならないでください!NVidiaカードでは、8x8ブロックのスクリーンピクセルはすべて、最も必要な深さまで繰り返し処理され、8x8ピクセルのブロックは任意の順序で実行できる、などと誰かが言ってくれることを期待していました。それは本当ではありません、それは私が人々が共有できることを望んでいる一種の知恵です。Larrabeeへのリンク、うーん、かなり間接的です。
ウィル

彼がララビーについて話しているようではないようですが、スタンフォードの男は2年後の2010年に同じ講演をしました(ここで見ることができます)。彼の数字から、whileループを考慮して、計算を「終了」させるピクセルがパフォーマンスを補うかどうかはわかりませんでした。CUDAでは、スレッドはバリアで待機します。類推で、シェーダースレッドはどうなりますか?
teodron、2012

@teodronええ、私はCUDAの理解を取り入れてGPUに適用しました。私は彼らがロックステップにいると確信していますが、私はチャイムに精通している誰かをお願いします。とにかく、ここの何か関連williamedwardscoder.tumblr.com/post/26628848007/rod-marching
ウィル

回答:


8

GDC 2012でGPU距離フィールドレイマーチング(およびその他のトピック)についての素晴らしい講演がありました:http : //directtovideo.wordpress.com/2012/03/15/get-my-slides-from-gdc2012/

パフォーマンスに関する限り、最新の(DX11クラス)グラフィックスカードは、32(NVIDIA)または64(AMD)の「スレッド」をロックステップで実行するSIMDユニットでシェーダーを実行します。これらのグループは、ワープまたはウェーブフロントとしてさまざまに知られています。ピクセルシェーダーの場合、各スレッドは1ピクセルに相当するため、SIMDユニットがピクセルの8x4(NVIDIA)または8x8(AMD)ブロックのようなものを一緒に処理していると思います。分岐とフロー制御は波面ごとに行われるため、波面内のすべてのスレッドは、その波面内の最も深い個々のピクセルと同じ回数だけループする必要があります。SIMDレーンマスクは、すでに終了したピクセルの実行をオフにしますが、波面のフロー制御全体を静かに実行する必要があります。これはもちろん、分岐が一貫している場合、システムがはるかに効率的であることを意味します。

私の経験では、波面のすべてのスレッドが同じように分岐しても、分岐オーバーヘッドは依然としてかなり高いです。ループを展開して分岐オーバーヘッドの一部を償却することにより、パフォーマンスが向上する場合があります。ただし、それはもちろん、各ループ反復で実行している作業量によって異なります。ループ本体に十分な「もの」が含まれている場合、アンロールしても成功しません。



0

動的分岐に関しては、もう1つ注意点があります(明白かもしれませんが、一部の人にとっては注目に値するかもしれません):展開されたループのパフォーマンスに深刻な影響を与える可能性があります(繰り返し数が一定でない場合、ループを展開できません) 。


-4

int s = 0;

ここでfor(int k = 1; k <= n; k ++){s + = k;}はs = n *(n + 1)/ 2と同じです

そのため、一般的には当てはまりません:D


1
ここで何を伝えようとしているのか、それが質問とどう関係しているのか誰もわからないので、あなたは多くの反対投票をしているかもしれません。
doppelgreener 2012
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.