Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: So Jun 16, 2024 06:33

Foren-Übersicht » Programmierung » Shader
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 16 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Autor Nachricht
 Betreff des Beitrags: Shaderlänge und Effizienz?
BeitragVerfasst: Mi Dez 12, 2007 11:33 
Offline
DGL Member

Registriert: Sa Sep 29, 2007 18:43
Beiträge: 38
Wohnort: STR / BLN / LAU
Hallo,

ich bin im Moment mit Benchmarking einer GPGPU-Anwendung beschäftigt und habe grausige Zeiten ermittelt.
Nun habe ich gelesen, das ein zu langer Shader Performance-Einbußen mit sich bringt und man doch mehrere kleine machen sollte.

Stimmt das? Kann jemand, vielleicht sogar aus Erfahrung, eine Bestätigung geben und vielleicht eine Begründung?
Ab wann ist ein Shader zu groß????

MfG
Daniellus

_________________
Tu es oder tu es nicht!
Tu es hier und jetzt oder tu es nicht hier und jetzt!
Aber tu niemals etwas und denke du würdest es lieber nicht tun....


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Dez 13, 2007 00:09 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Sep 23, 2002 19:27
Beiträge: 5812
Programmiersprache: C++
Die Länge eines Shaders bestimmt ja letztendlich (je nach verwendeten Befehlen) wie viele Instruktionen er benötigt, also können lange Shader durchaus langsamer sein. Was aber wahrscheinlicher ist, sind die Befehle und Strukturen die du verwendest. Die GPU ist ja eine spezialisierte PU (im Gegensatz zur CPU) und je nach Aufbau deiner Shader und genutzten Befehlen kann dieser durch eben diese je nach GPU recht langsam werden. Vor allem dynamischer Verzweigung (if/else) ist je nach GPU sehr langsam, auf alten Karten (z.B. R300) werden die Zweige dann sogar alle ausgeführt und einfach das unwahre Ergebnis überschrieben (alte GPUs unterstützen halt keine dynamische Verzweigung). Auch solche Sachen wie Sinus und Cosinus verbrauchen sehr viele GPU-Rechenzyklen, und je nach GPU kann es sein dass deine Schleifen entrollt werden (meist ältere GPUs).

Bei der Shaderprogrammierung gibt es also sehr viele Geschwindigkeitsfallen, da sollte man also z.B. nie nen riesigen "Übershader" mit vielen Verzweigungen schreiben, sondern eher spezialisierte Shader. Also ein Shader der via If auf 8 verschiedene Lichtquellen prüft ist mit Sicherheit langsam. Dazu kommt dann auch noch der Unterschied zwischen den verschiedenen GPUs. Was also auf einer Karte schnell ist (wenige Instruktionen braucht) ist auf einer anderen evtl. sehr langsam, oder läuft sogar (der schlimmste Fall) in Software.

_________________
www.SaschaWillems.de | GitHub | Twitter | GPU Datenbanken (Vulkan, GL, GLES)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Dez 13, 2007 10:18 
Offline
DGL Member

Registriert: Sa Sep 29, 2007 18:43
Beiträge: 38
Wohnort: STR / BLN / LAU
Vielen Dank erstmal...

Was heißt denn "entrollt"?
Bei mir erschien dies mal als Compiler -oder Linkermeldung. Weiß aber nicht mehr in welchem Zusammenhang.

Wenn ich nun mehrer Shader schreibe, wie funktioniert das genau?

Ich müsste meinen Shader so teilen, das ich Zwischenergebnisse von Shader zu Shader reiche.
Damit sind die nachfolgenden Shader abhängig von Ergebnis des vorherigen.

Werden die Shader in der Reihenfolge für jedes Fragment ausgeführt, in der ich sie aktiviere?

MfG

_________________
Tu es oder tu es nicht!
Tu es hier und jetzt oder tu es nicht hier und jetzt!
Aber tu niemals etwas und denke du würdest es lieber nicht tun....


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Dez 13, 2007 14:27 
Offline
DGL Member
Benutzeravatar

Registriert: Sa Aug 18, 2007 18:47
Beiträge: 694
Wohnort: Köln
Programmiersprache: Java
entrollt bedeutet, dass eine schleife:
Code:
  1.  
  2. for (i=1; i<=5; i++)
  3. {
  4.   a++;
  5. }
  6.  

ungefähr so aussähe
Code:
  1.  
  2.   a++;
  3.   a++;
  4.   a++;
  5.   a++;
  6.   a++;
  7.  


bzgl. Shader:

Zitat:
Wenn ich nun mehrer Shader schreibe, wie funktioniert das genau?

also ich habe für terrain, wasser und himmel jeweils einen eigenen shader.

Zitat:
Ich müsste meinen Shader so teilen, das ich Zwischenergebnisse von Shader zu Shader reiche.
Damit sind die nachfolgenden Shader abhängig von Ergebnis des vorherigen.


Der einzige Weg etwas zu "übergeben", wäre durch eine Textur oder FBO.

Zitat:
Werden die Shader in der Reihenfolge für jedes Fragment ausgeführt, in der ich sie aktiviere?

Man aktiviert genau einen shader gleichzeitig. :)
Wenn du nun z.b. per glVertex punkte ausgibst, werden die durch den Vertexshader und für jedes Fragment zwischen den Punkten durch den Fragmentshader gejagt. Etwaige varying variablen werden interpoliert.

_________________
Es werde Licht.
glEnable(GL_LIGHTING);
Und es ward Licht.


Zitat aus einem Java Buch: "C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off"

on error goto next


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Dez 14, 2007 09:43 
Offline
DGL Member

Registriert: Sa Sep 29, 2007 18:43
Beiträge: 38
Wohnort: STR / BLN / LAU
Ok, das habe ich nicht ganz geschnallt...
Ist das Entrollen jetzt positiv oder negativ, bitte um genauere Erklärung...


Zu den Shadern:

Also dann müsste ich ja für drei Shader drei Renderdurchläufe starten. Meine Zwischenergebnisse mit RTT speichern und dem nächsten Shader zur Verfügung stellen.
Das soll wirklich schneller gehen als alles in einem Shader zu berechnen?
Ich dachte ich könnte irgendwie drei Shader nacheinander in einem Renderprozess starten.
Ich glaube es liegt dann wohl an meinen Schleifen und Verzweigungen.

_________________
Tu es oder tu es nicht!
Tu es hier und jetzt oder tu es nicht hier und jetzt!
Aber tu niemals etwas und denke du würdest es lieber nicht tun....


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Dez 14, 2007 10:17 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Das Entrollen ist in jedem Fall negativ, denn das erzeugt mehr oder weniger eine kleine Kettenreaktion. Denn ohne Entrollen hast du eine Schleifenanweisung und einen Schleifenkörper. Wenn die Grafikkarte aber keine Schleifen kann, dann beinhält der resultierende Shader X Mal den Schleifenkörper. Selbst bei 2 Schleifendurchgängen dürfte der Shadercode bereits größer werden als mit einer Schleife. Wenn du jetzt aber 4 oder mehr Schleifendurchgänge hast, dann ist der resultierende Code noch mal ein ganzes Stück größer.

Und in erster Linie können ältere Grafikkarten keine Schleifen. Diese sind aber sowieso schon in der Shaderleistung/maximalen Shadergröße benachteiligt gegenüber den Karten die Schleifen können.

Zu dem Anderen: Du hast natürlich nur eine entsprechende Geschwindigkeit, wenn du auch auf der Grafikkarte arbeitest. Wenn der Shader aber zu groß ist, dann liegt die Karte bach und alles wird auf der CPU berechnet. Klar. Wenn du 3 mal die Ergebnisse zwischenspeichern musst, dann müssten die Texturdaten mehrfach kopiert werden und die Shader müssen sich jedes mal die Daten wieder neu holen. ABER. So würde es auf der GPU berechnet werden. Und dann ist es entsprechend schnell.

Grundsätzlich hast du aber recht. Wenn du alles in einem Shader und einem Durchgang rendern könntest, dann wäre das sicherlich der schnellste Weg. Aber auch nur, wenn alles auf GPU berechnet werden kann, denn dann würden die Zwischenschritte entfallen. Allerdings sind die GPUs was die Codegröße angeht etwas empfindlich und da scheinst du drüber zu liegen wodurch es dann auf die CPU ausgelagert wird. Ergo ist es noch viel langsamer als wie wenn man diverse Zwischenschritte hätte.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Dez 14, 2007 11:19 
Offline
DGL Member

Registriert: Sa Sep 29, 2007 18:43
Beiträge: 38
Wohnort: STR / BLN / LAU
Hui, das war jetzt erleuchtend...
Wenn der lange Shader läuft, dann kann ich nur noch meine Maus bewegen, aber keine Interaktionen mit der GUI ausführen (Fenster minimieren und so...). Ist der Shader nach gut 8 sekunden fertig, ja genau soooooooo lange, läuft alles wieder wie geschmiert.

Ist das ein Zeichen, das die GPU auslagert oder das sie echt heftig beschäftigt ist.
Wie zum Beispiel beim ruckeln von Spielen?

Kennt jemand eine Möglichkeit um eine Auslagerung zu entdecken?

MfG

_________________
Tu es oder tu es nicht!
Tu es hier und jetzt oder tu es nicht hier und jetzt!
Aber tu niemals etwas und denke du würdest es lieber nicht tun....


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Dez 14, 2007 11:27 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Sep 23, 2002 19:27
Beiträge: 5812
Programmiersprache: C++
Wenn es bei aktiviertem Shader wirklich 8 Sekunden braucht, dann läuft dein Shader definitiv in Software, und nicht mehr direkt auf der GPU. Dazu musst du in dein Shaderlog schauen, dort steht dann z.B. "Unsupported feature in fragment shader. Shader running in software", er läuft dann also ohne Beschleunigung durch die GPU, sowas stellt also den schlimmsten Fall dar. Du musst dann herausfinden warum dies so ist und den Shader ggf. abändern.

P.S. : Auf welcher Hardware läuft dein Shader?

_________________
www.SaschaWillems.de | GitHub | Twitter | GPU Datenbanken (Vulkan, GL, GLES)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Dez 14, 2007 12:34 
Offline
DGL Member

Registriert: Sa Sep 29, 2007 18:43
Beiträge: 38
Wohnort: STR / BLN / LAU
GeForce 8800 GTS...

_________________
Tu es oder tu es nicht!
Tu es hier und jetzt oder tu es nicht hier und jetzt!
Aber tu niemals etwas und denke du würdest es lieber nicht tun....


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Dez 14, 2007 12:55 
Offline
DGL Member

Registriert: Sa Sep 29, 2007 18:43
Beiträge: 38
Wohnort: STR / BLN / LAU
glGetShaderInfoLog liefert mir nur Warnungen wegen casts, mehr nicht...

_________________
Tu es oder tu es nicht!
Tu es hier und jetzt oder tu es nicht hier und jetzt!
Aber tu niemals etwas und denke du würdest es lieber nicht tun....


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Dez 14, 2007 12:57 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Sep 23, 2002 19:27
Beiträge: 5812
Programmiersprache: C++
Dann kann ich eigentlich nur noch mutmaßen, denn ohne den eigentlichen Shadercode (du hast ja nicht erwähnt was der Shader macht, bzw. wie er aussieht und welche Befehle er benutzt) kann man nicht wirklich erschliessen warum der so langsam ist. Evtl. benutzt du unpassende Formate, oder machst viele Texturenzugriffe im Vertexshader (die recht langsam sind), aber ohne Shadercode ist schwer zu sagen warum er so langsam ist.

_________________
www.SaschaWillems.de | GitHub | Twitter | GPU Datenbanken (Vulkan, GL, GLES)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Dez 14, 2007 13:35 
Offline
DGL Member

Registriert: Sa Sep 29, 2007 18:43
Beiträge: 38
Wohnort: STR / BLN / LAU
So, hier sind mal die Schleifen und Verzweigungen von dem Shader, die Berechnungen innerhalb der Schleifen und Verzweigungen, habe ich der Übersichtlichkeit entfernt.
Die Rechenoperationen belaufen sich auf ca. 100 Stück. Ich rechne mit Integern.

Code:
  1. "void main(void)"
  2. "{"
  3.     "for(iMask=0; iMask<28; iMask++)"
  4.     "{"
  5.  
  6.         "if(iMask<1)"
  7.         "{"
  8.             "for(rowSADMask=0; rowSADMask<7; rowSADMask++)"
  9.             "{"
  10.                 "for(colSADMask=0; colSADMask<7; colSADMask++)"
  11.                 "{"
  12.                     "if(iTempHorzEpi[indexHLMaskElem]<0)"
  13.                     "{"
  14.              
  15.                     "}"
  16.                
  17.                     "if(iTempVertEpi[indexHLMaskElem]<0)"
  18.                     "{"
  19.              
  20.                     "}"               
  21.                 "}"
  22.  
  23.             "}"
  24.       "}"
  25.      "else"
  26.      "{"
  27.          "for(rowSADMask=0; rowSADMask<7; rowSADMask++)"
  28.          "{"
  29.              "for(colSADMask=0; colSADMask<7; colSADMask++)"
  30.              "{"
  31.      "if(iTempHorzEpi[indexHLMaskElem]<0)"
  32.      "{"
  33.      
  34.                  "}"
  35.      "if(iTempVertEpi[indexHLMaskElem]<0)"
  36.      "{"
  37.  
  38.                  "}"
  39.               "}"
  40.            "}"
  41.         "}"
  42.            
  43.        "if(iaScore[iMask]<iMinScore)"
  44.        "{"
  45.                
  46.        "}"
  47.     "}"//loop mask
  48.  
  49.    "for(iDispCounter=0; iDispCounter<28; iDispCounter++)"
  50.    "{"
  51.       "if( (iaScore[iDispCounter]<iThreshold) && (iNumScoresUnderThres<2) )"
  52.       "{"
  53.        
  54.       "}"
  55.       "else"
  56.       "{"
  57.     "if(iNumScoresUnderThres==2)"
  58.     "{"
  59.  
  60.     "}"
  61.        "}"
  62.     "}"
  63.        
  64.     "if( (iaFinalDisp[1] == (iaFinalDisp[0]+1) )"
  65.     "{"
  66.         "if(iDispAtMinScore < iMinDisp)"
  67.         "{"
  68.  
  69.         "}"
  70.        "else"
  71.        "{"
  72.  
  73.         "}"
  74.     "}"
  75. "}";


Was sagt ihr? Viel oder nicht viel Schleifen?

_________________
Tu es oder tu es nicht!
Tu es hier und jetzt oder tu es nicht hier und jetzt!
Aber tu niemals etwas und denke du würdest es lieber nicht tun....


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Dez 14, 2007 15:10 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Sep 23, 2002 19:27
Beiträge: 5812
Programmiersprache: C++
Oha, so ein Konstrukt ist auf ner CPU evtl. noch halbwegs schnell, aber auf der GPU vernichtest du damit jegliche Performance. Bei so einem Shaderaufbau verwundert es auch nicht, dass sogar eine 8800 in die Knie geht. Du hast mehrfach verschachtelte, recht lange Schleifen, und machst dann sogar noch innerhalb der Schleifen dynamische Verzweigungen, das ist definitiv zu viel für die GPU. Du musst hier deinen Shader also unbedingt anders aufbauen, bzw. optimieren oder in mehrere Passes unterteilen.

Man sollte immer daran denken dass die GPU immernoch eine spezialisierte PU ist, egal wie flexibel die aktuell auch sein mögen. Was also auf der CPU ohne großen Aufwand klappt (Verschachtelte Schleifen mit behinhaltender dynamischer Verzweigung) kann auf der GPU extremst langsam werden.

_________________
www.SaschaWillems.de | GitHub | Twitter | GPU Datenbanken (Vulkan, GL, GLES)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Dez 14, 2007 15:18 
Offline
DGL Member

Registriert: Sa Sep 29, 2007 18:43
Beiträge: 38
Wohnort: STR / BLN / LAU
Vielen Dank...nun muss ich wohl noch etwas basteln...
ich melde mich nächste Woche nochmal, wenn ich den Shader gesplittet habe.

Schönes we...

_________________
Tu es oder tu es nicht!
Tu es hier und jetzt oder tu es nicht hier und jetzt!
Aber tu niemals etwas und denke du würdest es lieber nicht tun....


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Dez 20, 2007 11:03 
Offline
DGL Member

Registriert: Sa Sep 29, 2007 18:43
Beiträge: 38
Wohnort: STR / BLN / LAU
Hallo,

es findet wohl wirklich eine Auslagerung auf die CPU statt. Ich habe die CPU-Last, während der Shader läuft, auf 100% ermittelt.
Glaube das dürfte ein Indiz sein.
Das teilen des Shaders habe ich nicht vorgenommen. Das erste Zwischenergebnis, welches ich nehmen könnte ist ein Array
mit 28 Feldern, ich bräuchte 7 MRT's, welche alle im 2. Shader gelesen werden müssten. Ich habe mich aus zeitl. Gründen dagegen entschieden
und lieber ein paar Tests gemacht was den Datentransfer,Texturzugriffe und Effizienz angeht.
Die Versuchsreihe ist ein Vergleich GPU-CPU:

Pc: Athlon 3 GHz, 2 GB RAM
GraKa: GeForce 8800 GTS

Der x-wert ist beliebig und stammt aus einer 512x512 Textur.
Dementsprechend finden auch 512x512 Berechnungen auf GPU/CPU statt.
Es wurde ein Mittelwert aus 1000 Zyklen gebildet.
Die Zeiten sind inkusive Datentransfer.

Berechnung 4x^2+3x+10

GPU: 2,5 ms
CPU: 1,9 ms

Berechnung 4x^5+3x+10

GPU: 2,5 ms
CPU: 2,9 ms

Berechnung 4x^10+3x+10

GPU: 2,5 ms
CPU: 4,8 ms

Wie man sieht ist die GPU-Zeit, trotz steigender Rechenoperationen, immer gleich-->vermutlich Texturzugriffe.

Berechnung 4x^2+3x+10 ohne Texturzugriffe, sondern mit lokalem x

GPU: 1,2 ms
CPU: 1,9 ms

Ohne Texturzugriffe wirds schneller, der Prozessor liegt tatsächlich brach, trotz 64 GB Speicheranbindung zum VRAM.
Alle Angaben die ich hier gemacht habe sind ohne Gewähr ;-)
Vielleicht kann dies jemand mit ähnlichen Erfahrungen bestätigen?

_________________
Tu es oder tu es nicht!
Tu es hier und jetzt oder tu es nicht hier und jetzt!
Aber tu niemals etwas und denke du würdest es lieber nicht tun....


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 16 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Foren-Übersicht » Programmierung » Shader


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 22 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
cron
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.430s | 17 Queries | GZIP : On ]