6

最新バージョンの Chrome (および Firefox) を使用して WebGL (GLSL ES 1.0) のフラグメント シェーダーを作成しており、反復アルゴリズムを作成しました。

まず第一に、ループの長さがかなり制限されているという難しい方法を見つけました(ドキュメントは、コンパイル時に推測可能でなければならないと言います。つまり、一定であるか、非常に近い必要があります)。

さらに、 ( 、標準に従って実装する必要forがある唯一のループであるため) を作成する必要があります。このループは長くなる可能性がありますが、ほぼ毎回終了前に中断します。

ここで、最大数を高く設定すると、シェーダーのコンパイルとリンクにより多くの時間がかかることに気付きました。したがって、私が間違っていない限り、コンパイラはループの巻き戻しを行います。

何かできるかどうかはわかりませんが、いくつか試してみましたが、ループで呼び出された場合でも、コンパイラは関数をインライン化するようです。

シェーダーが約 100 回のループの反復をコンパイルするのに 1 分もかかるのは普通ではないと思います。それとも私は間違ったことをしていますか?フラグメント シェーダーでの 100 回の反復は、GPU にとって多すぎますか? コンパイル後は問題なく動作するように見えるからです。

4

3 に答える 3

6

This is one of the unfortunate realities of GLSL. It would be great if we could do an offline compile and send in bytecode, or if we had the ability to specify flags at compile time or so on, but that's just not how the spec works. You are entirely at the mercy of the driver manufacturer. If NVIDIA/ATI thinks loop unrolling is good for you, your loop is gonna get unrolled.

I do question what it is that you are doing that requires so much looping, though. Shaders are not really the right place to be doing super complex looping or branching calculations. You'll certainly take a performance hit for it. If you're not worried about realtime performance, then perhaps a large compile hit at the start of your program isn't so bad. If you are concerned about the rendering speed of your app then you likely need to re-evaluate your shaders complexity.

于 2012-04-26T18:35:05.803 に答える
5

あなたはシェーダーが最大約100回の繰り返しでループをコンパイルするのに1分以上かかると言いました.これはあなたの問題がANGLEに関連している可能性があると私に思わせます

ANGLE は、Windows OS 上の WebGL 対応ブラウザーに組み込まれているソフトウェアで、GLSL シェーダーを取得し、実行時にそれを Direct3D HLSL シェーダーに変換します。ほとんどの Windows マシンには、OpenGL ドライバーに比べて新しい Direct3D ドライバーが搭載されているため、デフォルトの動作ではすべてを D3D に変換すると考えられています。私の経験では、これは遅くなる可能性があり、特にあなたが説明したように長いループでは遅くなる可能性がありますが、多くの Windows ユーザー、特に Intel ベースのグラフィックスを使用するユーザーが必要としています。

Windows を実行していて、nVidia や AMD のかなり新しいものなど、高品質の OpenGL ドライバーを使用している場合は、ANGLE を無効にして問題が解決するかどうかを確認できます。Google Chrome では、Chrome アイコンを編集--use-gl=desktopしてコマンドライン パラメータとして (アイコンの「ターゲット」フィールドに) 追加し、ブラウザを再起動することでこれを行います。Firefox の場合は、検索ボックスにアクセスabout:configして入力webglし、それを探しwebgl.prefer-native-glて true に設定できます。

ANGLE を無効にしてシェーダーを再試行すると、コンパイル時間が改善される可能性があります。これは Windows のみの問題であるため、他のプラットフォームでこれらの設定を編集しても影響はありませんが、他のすべてのプラットフォームはすべてネイティブ OpenGL を直接使用していると思います。

于 2012-04-27T19:23:11.803 に答える
1

悲しいことに、AMDはこれをサポートしていないかもしれませんが、NVidia には素晴らしいプラグマ アンロール ディレクティブがあると思います。逆に困っている人はGLSLで「#pragma optionNV (unroll all)」で呼び出すのですが、以下のようにすれば展開が防げると思います。NVidia フォーラムでの DenisR の 2008 年の投稿を引用します。

デフォルトでは、コンパイラは既知のトリップ カウントで小さなループを展開します。ただし、#pragma unroll ディレクティブを使用して、特定のループの展開を制御できます。ループの直前に配置する必要があり、そのループにのみ適用されます。オプションで、ループをアンロールする必要がある回数を指定する数値が続きます。

たとえば、次のコード サンプルでは:

#pragma unroll 5

for (int i = 0; i < n; ++i)

ループは 5 回展開されます。アンロールがプログラムの正確性に影響を与えないことを確認するのは、プログラマーの責任です (上記の例では、n が 5 より小さい場合、影響を受ける可能性があります)。

#pragma unroll 1 

コンパイラがループをアンロールしないようにします。

#pragma unroll の後に数値が指定されていない場合、トリップ カウントが一定であればループは完全に展開されます。それ以外の場合はまったく展開されません。

だから私はそれを想像するでしょう

#pragma optionNV (unroll 1)

GLSL (および WebGL?) で動作する可能性があります。(たとえば、StackOverflow の質問のselective-nvidia-pragma-optionnvunroll-allは、少なくとも一部のプラットフォームでは、これが GLSL で機能する可能性があることを暗示しているようです。)

近年、AMD が unrolling プラグマをサポートしている可能性があることを示唆しているようですが (GLSL ではサポートされていない可能性があります)、私は詳しくなく、試したこともありません: AMD OpenCL カーネルでのループの展開

(Chrome/Firefox で WebGL を介して GLSL を使用する場合、またはその他のシナリオでさえ、GLSL コンパイルがANGLEを介してパイプされる可能性があることに注意してください。これは、Windows の HLSL バックエンドにレンダリングされる可能性があります。私はこれについて非常に限られた理解しか持っておらず、ドン「情報を広めたくないので、絶対に引用しないでください。これまでにこの問題について収集した情報を共有する必要があると感じただけで、この回答を喜んで編集します (または、人々はこの回答を自由に編集する必要があります)。 ) より多くの確認された情報が利用可能になるにつれて. )

于 2016-10-21T05:39:33.653 に答える