シェーダーのループパフォーマンス


11

動的ループ関数をシェーダーに統合するための最良の方法は何ですか?

まず、動的配列は不可能であるようです。では、最大サイズの配列を作成し、その一部のみを埋めるか、定義済みのサイズで配列を定義する方が良いでしょうか?

次に、この配列を反復処理する最良の方法は何ですか?

4〜128回の反復で、展開されたループまたは動的ループを使用する方が良いですか。また、事前定義された最大反復回数まで展開してから、などの条件で停止できることも確認しましたif (i == myCurrentMaximumIterationNumber)


2
配列とループで何をしようとしていますか?これはどういうわけか私にXY問題のように聞こえるので、私は尋ねています。GPUで条件とループを使用する最良の方法はそれらの使用を控えることであるため、場合によっては配列とループを使用する代わりに、さらに良い方法があるかもしれません。
Nero

現在機能しているスクリーンスペースのサブサーフェススキャッタリングエフェクトを実装しています。しかし、パフォーマンスに応じてカーネルを使用する方法については、いくつか疑問があります。私は最大の配列サイズを実行し、一部のみを入力し、現在使用されている配列コンテンツに関連する動的な反復回数の動的ループを使用することを選択しました。たとえば、パフォーマンスに応じてシェーダーをプログラミングする際には、知っておくべきことがあると思います。そして、私の意見では、ループは、いくつかのルールとおそらく「良い習慣」に従うかもしれない一般的なパフォーマンスのトピックですが、それについての良い答えは見つかりませんでした。
MaT 2016年

回答:


6

シェーダーコンパイラーは、初期のハードウェアにはフロー制御がなかったことが多く、最近のハードウェアのコストが変動する可能性があるため、アンロールについて非常に積極的です。積極的にテストしているベンチマークと関連するさまざまなハードウェアがある場合は、何が起こるかを確認してみてください。動的ループは、静的ループよりも開発者の介入の影響を受けやすくなりますが、ベンチマークを利用できる場合を除き、コンパイラーに任せることをお勧めします。ベンチマークがあれば、探索は価値があります(そして楽しい)。

ところで、GPUの動的ループによる最大の損失は、波面/ワープの個々の「スレッド」が異なる時間に終了することです。後で停止するスレッドは、早期に終了するすべてのスレッドにNOPの実行を強制します。

ネストされたループは注意深く検討する必要があります。ゼロのランをエンコードするブロックベースのエントロピーデコーダーを実装しました(JPEGのような圧縮の場合)。自然な実装は、タイトな内部ループで実行をデコードすることでした。これは、多くの場合、1つのスレッドのみが進行していたことを意味します。ループをフラット化し、実行を現在デコードしているかどうかを各スレッドで明示的にテストすることにより、固定長ループを通じてすべてのスレッドをアクティブに保ちました(デコードされたブロックはすべて同じサイズでした)。スレッドがCPUスレッドの場合、変更はひどいものでしたが、実行中のGPUでパフォーマンスが6倍になりました(それでもひどい-GPUをビジー状態に保つための十分なブロックがありませんでした-しかし、それは概念実証でした)。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.