Engine Performance Verbessern

  • Hallo,


    Wir haben als Feedback "Eure Framerate ist sehr niedrig auf den Abgaberechnern - dafür gibt es keine Entschuldigung. Schaut, dass ihr mindestens 60 FPS durchgehend erreicht."
    Wo setzten wir da am Besten an?


    Texture Uniforms?
    Shader Optimierung?


    Lg.

  • Ihr könnt ein paar Millisekunden sparen, wenn ihr glGetUniformLocation() nur einmal macht und nicht in jedem Render-Durchlauf. Aber darauf würde ich mich nicht stürzen.
    Typischerweise spart man recht viel wenn man kleinere Framebuffer Texturen, Shadow Maps, etc. benutzt.
    Oder Modelle mit super vielen Polygonen oder super viele Modelle. Da kann man zB mit Culling nachhelfen.
    Ansonsten könnten es Schleifen im Shader sein (zB Anzahl von Samples reduzieren, etc.)


    Aber insgesamt, um unter 60 FPS zu bekommen, macht man etwas bestimmtes sehr falsch. Weil die Abgaberechner recht leistungsstark sind.
    Daher: Anstatt einfach zu raten, würde ich vorschlagen, dass ihr selbst im Code die Zeit misst und rausfindet zB welcher Render-Pass am meisten Zeit verbraucht. Oder welcher Teil des Programms besonders viel Zeit braucht.


    Es gibt hier kein Allgemeinrezept. Sehr spezifisch für euer Programm - daher messen und testen.


    Edit: ihr könnt auch einzelne Effekte ausschalten und die Framerateänderung beobachten

    Stefan Spelitz
    [Computergraphik UE Tutor 2017SS]

    Edited once, last by 2#4u ().

  • Wir haben mal ein unseren VBO optimiert und texturen komprimiert.
    Bringt aber nicht sehr viel.


    Kann es auch sein das wird einfach zu viele glUniforms benutzen?


    Wir sind da schon recht freizügig was dass betrifft.


    Gibt es irgendwo best Practices wie wir das verbessern können?


    Uniform Buffers hab ich mir mal angeschaut. Ist das ein guter Ansatz?

  • Eure Szene ist wirklich überschaubar. Ihr habt nicht viel Geometrie, eure Haupteffekte sind Omni-directional Shadow Mapping und SSAO. Da gibt es nicht viel zu optimieren, da läuft was falsch, wenn das auf den Abgaberechnern mit zB einer GTX 960 nicht auf 60 FPS kommt.


    Ich weiß nicht genau was du mit VBO optimieren und Texturen komprimieren meinst, aber sei's drum.


    Dass es die Anzahl der uniforms betrifft glaub ich auch nicht. Im Allgemeinen sind uniform buffers schneller, aber den Weg würde ich an eurer Stelle jetzt nicht mehr gehen.
    Ich rate euch zu folgender Vorgehensweise:
    - OpenGL Debug Context einbauen und prüfen, ob Fehler und/oder Performance Warnings gemeldet werden
    - Den Fehlerbereich einschränken
    - D.h. Rausfinden welcher Teil vom Code wie lange läuft
    - D.h. Code auskommentieren und messen was sich verändert
    - Das ihr werdet das vss. zuerst auf der C++ Seite machen
    - Und dann entsprechend Code auf der GLSL Seite auskommentieren


    Wenn ihr dann rausgefunden habt welche Zeilen Code dafür verantwortlich sind, dann kann ich euch hoffentlich Vorschläge machen wie ihr das verbessern könnt.
    Es ist eigentlich ganz einfach, ihr habt funktionierenden Code, der langsam ist, aber ihr wisst nicht warum.
    Daher Code entfernen, prüfen um wieviel es schneller wird und den größten Brocken bestimmen!

    Stefan Spelitz
    [Computergraphik UE Tutor 2017SS]

  • Quote


    Eure Szene ist wirklich überschaubar. Ihr habt nicht viel Geometrie, eure Haupteffekte sind Omni-directional Shadow Mapping und SSAO. Da gibt es nicht viel zu optimieren, da läuft was falsch, wenn das auf den Abgaberechnern mit zB einer GTX 960 nicht auf 60 FPS kommt.


    Ja das stimmt.


    Ok das mit dem Debug Context mach ich jetzt.


    Eine Sache ist aber Klar, unsere eine Pointlight Quelle Kosten ca 10 fps.
    Also Ich hab mal alle Bäume raus, und hab ca. 25 fps.
    Dann geb ich den pointlight Quelle auch raus und hab so 35.


    Die Shader von der Point light source sind eher standard.

  • Wieviele FPS habt ihr wenn ihr eine leere Szene rendert? Wieviele wenn ihr keine Lichter und Effekte aktiviert? Ich würde in der Renderloop anfangen von Hinten weg Features auszukommentieren und zu schauen welcher Teil wieviele Millisekunden kostet (FPS sind nicht sehr gut zum Vergleichen).

    Bernhard Steiner
    [ECG/RTR Übungsleitung]

  • Danke für die Antworten. Der nächste Post wird ein bisschen lang.


    Also, ich hab mal im Visual Studio den Performance Analyzer drüber laufen lassen.


    Die Bewertung sah mal so aus:


    ALL.jpg
    DirectedLight_SetData.jpg
    Light_setData.jpg
    perspectiveCube_SetData.jpg
    PointLight_SetData.jpg


    Wir verbringen sehr viel Zeit Uniforms für die Lichter zu setzen. Eigentlich ziemlich Sinnlos da wir 90% der zeit nur die Position brauchen. Und alles andere nur wenn wir den GBuffer rendern.
    Auch die cubemap braucht sehr viel Zeit.


    Der Zweite wichtige Punkt ist das viel Zeit in der ig75...dll verbracht wird. Das ist mein Graphiktreiber. Ich hab nur einen Laptop.
    Das ist ein Zeichen dafür das wird unsere Shader optimiern müssen?

  • Nach dem ersten Optimierungsschritt schaut alles mal so aus:


    Cubemap.jpg
    Directed.jpg
    draw.jpg
    Overview.PNG
    Generel ist das SetLight viel besser geworden. Ich weiß nicht wie viel ich da noch vebessern kann.
    Die Cubemap hab ich um ein /4 geteilt. Hat sich nicht alzu viel verbessert.


    Bin also noch 50% am Driver.
    Ich schau jetzt mal wie sich das am Abgaberechener auswirkt.

  • Ok. Auf meinem Laptop hab ich jetzt laut meinem fps Counter ca. 40fps?


    Ich habs laut http://www.opengl-tutorial.org/miscellaneous/an-fps-counter/ kurz rein geschrieben.


    2017-01-19.png
    framerate.PNG


    Also sollt ich am Abgaberechner > 60 fps haben (?)


    Auch noch wichtig. Unser "alpha blending" hab ich ausgeschalten. Da wir das eher reingehackt haben. Wir rendern die Szene eig 2x. und überschreiben mehr oder weniger unsern Albedo gBuffer bei 2ten mal.
    Ich schau ob ich das auch verbessern kann. War eig. nur für die Blätter der Baüme.

  • Ok. Auf meinem Laptop hab ich jetzt laut meinem fps Counter ca. 40fps?


    Ich seh keine 40 FPS in den Screenshots. Ich seh ~ 40 ms bzw. 6.5 ms. Das sind 25 FPS bzw 150 FPS.



    Also sollt ich am Abgaberechner > 60 fps haben (?)


    Ausprobieren. Anders kann man das nicht wissen.



    Der Zweite wichtige Punkt ist das viel Zeit in der ig75...dll verbracht wird. Das ist mein Graphiktreiber. Ich hab nur einen Laptop.
    Das ist ein Zeichen dafür das wird unsere Shader optimiern müssen?


    Ich vermute es, ja. Es wäre aber wichtig rauszufinden welcher Shader das ist.


    -------------


    Wie ich in der ersten Antwort schon geschrieben habe, könnt ihr versuchen eure glUniformLocation() Aufrufe nur einmal pro Shader zu machen und nicht ständig beim Rendern.
    Man sieht in einem Screenshot zB dass glGetUniformLocation() mit 3.3 % mehr Resourcen verbraucht als das darauf folgende setzen der 4x4 Matrix mit glUniformMatrix4fv mit 2.7 %.


    Das sind einzeln gesehen nur Peanuts, aber ihr ruft das so oft auf und es ist so einfach vermeidbar, wenn man die location einmalig holt und zB auf eine Membervariable zwischenspeichert, dass es einen Versuch wert ist.

    Stefan Spelitz
    [Computergraphik UE Tutor 2017SS]

  • Quote


    Das sind 25 FPS bzw 150 FPS.


    Ok also 150 am Abgaberechner.


    Quote


    Wie ich in der ersten Antwort schon geschrieben habe, könnt ihr versuchen eure glUniformLocation() Aufrufe nur einmal pro Shader zu machen und nicht ständig beim Rendern.


    Werd ich machen.


    Danke!.