Registriert: Di Apr 29, 2008 18:56 Beiträge: 1213
Programmiersprache: Delphi/FPC
Hey Leute,
ich hatte heut ne mehr oder weniger dumme Idee. Und zwar haben einige ja bei unserer Engine sehr geringe FPS-Raten und trotzdem rammelt sich die CPU zu Tode, weil sie auf die synchronen OpenGL Calls warten muss. Dabei geht natürlich haufen Zeit verloren, weil alles darauf wartet, das der aktuelle Datensatz an die Graka durchgereicht ist. Also was wäre wenn man die OpenGL Calls asynchron gestalten würde? Die Daten die man übergibt müssten dann kopiert werden. Übergaben per Pointer oder Funktionen die einen Rückgabewert haben werden trotzdem noch synchron ausgeführt. Im Render-Loop könnte man aber auf diese Funktionen verzichten, da kommen eh zum Großteil nur sowas wie VBO- oder Displaylisten-Calls, die aber bei aufwendigen Shadern auch etwas Zeit in anspruch nehmen können. Die relevanten Daten wie z.B. Positionen von bewegten Objekten und dergleichen würden also jetzt als Kopie in irgendeiner Queue darauf warten abgearbeitet zu werden. In der Zeit können schon die neuen Positionsdaten berechnet werden. Vorm SwapBuffers synchronisiert man das Ganze dann wieder für das nächste Frame. Jetzt ist die Frage, ob sich das lohnt, bzw. ob das irgendwo Probleme verursacht. Aus diesem Grund wollte ich das hier mal zur Diskussion stellen. Sollte das wirklich ne Sinnvolle alternative sein könnte man ja ne Art asynchrone dglOpenGL bauen...
Registriert: Mi Aug 14, 2013 21:17 Beiträge: 588
Programmiersprache: C++
Alle OpenGL-Calls sind bereits asynchron, wenn deren Sinn nicht explizit synchronisieren ist (z.B. glFlush). SwapBuffers synchronisiert auch, ist aber genau genommen auch kein OpenGL-Aufruf.
_________________ So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)
Registriert: So Aug 08, 2010 08:37 Beiträge: 460
Programmiersprache: C / C++ / Lua
Meine Idee (für meine Engine) ist ein Eventsystem zu nutzen. Wann immer ein OpenGL Call notwendig ist, wird ein Event erstellt. Diese werden alle _nacheinander_ abgearbeitet, also prinzipiell threadsafe. Da man die Daten direkt im Parameter der Events übergibt, kann man danach direkt weiterarbeiten.
Beispiel:
Rechenthread: Rechne Teil 1 Erstelle Event + übergebe Daten von Teil 1 Rechen Teil 2 Erstelle Event + übergebe Daten von Teil 2 usw, usf...
(gerade nicht allzuviel Zeit, kann es später genauer erläutern)
_________________ offizieller DGL Compliance Beauftragter Never run a changing system! (oder so)
Registriert: Mi Aug 14, 2013 21:17 Beiträge: 588
Programmiersprache: C++
Leute, ihr baut etwas, das schon fest in OpenGL implementiert ist. Hier ein Zitat aus dem Wiki:
DGL Wiki hat geschrieben:
Ein glDraw*** wird nicht sofort ausgeführt, d.h. die CPU erhält die Kontrolle zurück bevor die GPU fertig mit rendern ist. Erst beim vertauschen von Front- und Backbuffer ("SwapBuffers") oder einem expliziten glFinish wird synchronisiert. Folglich gebe zuerst der Grafikkarte was zu arbeiten, rechne dann deine Spiellogik, Physik, etc. auf der CPU und rufe dann erst SwapBuffers auf. Sowas geht natürlich nicht immer, aber man kann beispielsweise Physik und Rendern in zwei Frames aufspilten. Also du berechnest immer die Physik für das nächste Frame, während die GraKa das aktuelle Frame rendert. Siehe auch glFlush.
_________________ So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)
Es ist nirgends davon die Rede, dass OpenGL nicht bereits asynchron rendert. Das sollte jedem bekannt sein. (Hoffe ich zumindest...) Es ging im Eröffnungspost darum, dass die Datenübertragung zur Grafikkarte nicht asynchron durchgeführt wird. Ob das der Fall ist, bin ich mir nicht sicher. Ich denke zwar schon, aber selbst wenn ja, sollte zb. alleine durch den Treibercall einiges an Leistung verloren gehen. Auch alle Validierungen, das Umrechnen von Texturdaten in das interne Format oder Shaderkompilierung wird möglicherweise im Anwendungsthread erledigt. Wie das genau abläuft, weiß ich allerdings auch nicht: Es sind nur Vermutungen. Bei DirectX gibt es einen ähnlichen Mechanismus scheinbar bereits eingebaut: http://msdn.microsoft.com/en-us/library/windows/desktop/ff476892(v=vs.85).aspx Aus Sicht von Multithreading wohl schon sinnvoll.
Ich habe jedenfalls auch schon darüber nachgedacht, die OpenGL-Calls vom Anwendungsthread zu entkoppeln und einen solchen Anweisungspuffer einzurichten, der dann threadsicher ist und einige lästige Dinge wie die Statehölle von OpenGL komplett wegkapselt und OpenGL Befehle zb. hinsichtlich ihrer Reihenfolge optimiert. Auch gibt es bei mir im Moment sehr viele Verzweigungen in der Art "Wird Extension XY unterstützt?", "Ist OpenGL x.y verfügbar?" oder "Gibt es DSA?". Mit einen OpenGL-Call-Thread könnte man dass leicht aus der Renderloop rausziehen.
Ich habe irgendwo hier im Forum bei den Projekten auch schon mal von einer OpenGL-VM gelesen, unter der ich mir etwas Ähnliches vorstelle.
Registriert: Mi Aug 14, 2013 21:17 Beiträge: 588
Programmiersprache: C++
OpenglerF hat geschrieben:
Es ging im Eröffnungspost darum, dass die Datenübertragung zur Grafikkarte nicht asynchron durchgeführt wird.
Auch das läuft asynchron, außer wenn noch Rendervorgänge auf der Grafikkarte laufen, die von oder in einen Buffer rendern, der durch die Datenübertragung modifiziert wird. Das Auslesen Übertragen des Inhalts eines FBOs an den Client z.B. würde eine Synchronisation hervorrufen, wenn noch in dieses FBO gerendert wird. Grundsätzlich gilt aber: Es wird nur dann implizit synchronisiert, wenn es nicht sinnvoll anders möglich wäre.
_________________ So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)
Registriert: Di Apr 29, 2008 18:56 Beiträge: 1213
Programmiersprache: Delphi/FPC
Richtig und genau darum geht es, da beim DeferredRendering mitunder sehr viele FBOs im Spiel sind kommt es da unweigerlich zu synchronen Calls. Bei uns ist es so, das alle vorberechneten FBOs im letzen RenderPass vereint werden und dann in den eigentlichen FrameBuffer geschrieben werden. Heißt die CPU wartet ein ganzes Frame lang darauf das die FBOs fertig sind...
Registriert: Mi Aug 14, 2013 21:17 Beiträge: 588
Programmiersprache: C++
Warum? Liest die CPU Daten aus dem FBO aus? So wie ich Deferred Rendering verstanden habe, werden die FBOs, die den G-Buffer bilden, nur als Textur eines Fullscreen-Quads gebunden. Dass dies erst geht, wenn der G-Buffer fertig ist, darum kümmert sich der Treiber ganz ohne dass mit der Client-Seite (CPU) gesynct wird.
_________________ So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)
Registriert: Di Apr 29, 2008 18:56 Beiträge: 1213
Programmiersprache: Delphi/FPC
Direkt ausgelesen wird nix, nur entsprechend gebunden. Ich weiß leider nicht wo genau der Treiber da das sync macht. Wenn das erst beim SwapBuffers passiert, würde die CPU Last nicht so hoch sein, denn auf der CPU passiert fast nix. Am bessten wir messen das ma mit nem Profiler durch, dann sind wir schlauer^^
Registriert: Mi Aug 14, 2013 21:17 Beiträge: 588
Programmiersprache: C++
Also nach meinem Verständnis von OpenGL und dem, was im offiziellen Synchronization-Artikel steht, sollte das Binden einer Textur keine Synchronisation hervorrufen.
Bergmann89 hat geschrieben:
Wenn das erst beim SwapBuffers passiert, würde die CPU Last nicht so hoch sein
Wie kommst du zu dieser These?
Edit: Hast natürlich recht...
_________________ So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)
Zuletzt geändert von glAwesome am Di Jan 14, 2014 20:08, insgesamt 1-mal geändert.
Mitglieder in diesem Forum: 0 Mitglieder und 10 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.