GLSL-Shader führt die Schleife nicht aus, wenn sie benötigt wird

8

Mein 9600GT hasst mich.

Fragment Shader:

%Vor%

Wenn a=25 Programm mit 3000 fps läuft.
Wenn a=26 Programm mit 20 fps läuft.
Wenn die Größe von aa & lt; = 32 Problem nicht angezeigt wird.
Ansichtsfenstergröße ist 1000x1000.
Problem tritt nur auf, wenn die Größe von aa & gt; 32 ist.
Wert von a als Schwellenwert variiert mit den Aufrufen des Arrays innerhalb der Schleife ( aa[i]=aa[i+1]+aa[i-1] gibt einen anderen Stichtag).
Ich weiß, gl_FragColor ist veraltet. Aber das ist nicht das Problem.

Meine Vermutung ist, dass GLSL den Loop nicht automatisch abrollt, wenn ein & gt; 25 und eine Größe (aa) & gt; 32. Warum. Der Grund, warum es von der Größe des Arrays abhängt, ist der Menschheit unbekannt.

Ein ziemlich ähnliches Verhalten wird hier erklärt:
Ссылка

Durch das manuelle Abwickeln der Schleife wird das Problem gelöst (3000 fps), selbst wenn aa size ist: 32:

%Vor%     
user2464424 01.09.2013, 10:54
quelle

1 Antwort

5

Ich füge hier nur eine zusammenfassende Antwort auf die Kommentare ein, so dass dies nicht mehr als unbeantwortet erscheint.

  

"# pragma optionNV (alles auflösen)"

behebt das unmittelbare Problem auf nvidia.

Im Allgemeinen sind GLSL-Compiler jedoch sehr implementierungsabhängig. Der Grund, warum es einen Rückgang von genau 32 gibt, kann leicht erklärt werden, indem man eine Compiler-Heuristik wie "Löse Schleifen länger als 32" nicht aufruft. Die große Geschwindigkeitsdifferenz kann auch von einer nicht abgerollten Schleife kommen, die Konstanten verwendet, während eine dynamische Schleife einen adressierbaren Feldspeicher benötigt. Ein weiterer Grund könnte sein, dass beim Abwickeln der toten Code-Eliminierung eine konstante Faltung einsetzt, die den gesamten Loop auf Null reduziert.

Der am besten tragbare Weg, um dies zu beheben, ist wirklich manuelle Abrollen oder noch besser manuelles konstantes Falten. Es ist immer fraglich, Konstanten in einem Fragment-Shader zu berechnen, der außerhalb berechnet werden kann. Einige Treiber können es für einige Fälle fangen, aber es ist besser, sich nicht darauf zu verlassen.

    
starmole 16.02.2014, 03:50
quelle