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

Aktuelle Zeit: Sa Mai 18, 2024 05:16

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



Ein neues Thema erstellen Auf das Thema antworten  [ 18 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Autor Nachricht
 Betreff des Beitrags: Multithreaded Rendering
BeitragVerfasst: Fr Aug 10, 2012 12:51 
Offline
DGL Member

Registriert: Sa Mär 14, 2009 17:48
Beiträge: 99
Programmiersprache: D, Java, C++
Hallo,

ich möchte meinen Renderer Multi Threaded Designen, dazu möchte ich alle OpenGL Calls in dem einen Thread, und Scene Updates & Co in jeweils anderen Threads laufen lassen.

Ich hab mir folgendes überlegt und ausprobiert, jedoch bin ich damit nicht wirklich zufrieden ;-):

Ich habe in einem "FrameBuilding" Prozess alle nötigen RenderJobs vorberechnet und dann gesammelt an den Renderer gegeben, Problem dabei ist, dass diese "RenderJobs" jeweils eine "execute(...)" Methode haben und diese Methode führt nur sehr wenige GL Calls aus, d.h. für 2-3 GL Calls im Schnitt habe ich einen Methoden Aufruf, dass scheint mir relativ unperformant. (Beispiele für solche RenderJobs: GeometryUploadJob, GeometryUpdateJob, ProgramBindJob, GeometryBindJob, GeometryDrawJob, und viele andere mehr). Vorteil war: Im RenderThread passierte sogut wie garnixmehr außer das der reihe nach ausführen der RenderJobs. Im Update Thread kann alles optimal vorsortiert und überflüssige Jobs gecancelt werden.

Kann man diesen Ansatz so lassen? Gibt es deutlich sinnvollere Alternativen? Kennt ihr eine Art "Best Practice" zum dem Thema?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Multithreaded Rendering
BeitragVerfasst: Fr Aug 10, 2012 19:14 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Ich denke die Idee ist vom Prinzip gut, allerdings schlüsselst du das zu klein auf. Also ich schlage vor du erstellst im Update-Thread eine Liste der zu renderden Objekte (sichtbar und so) und sortierst diese. Der Render-Thread arbeitet dann diese Liste ab.

Ein solches RenderObject weiß ungefähr das folgende:
- Vertexbuffer (und ggf. Indexbuffer)
- Shader
- Material (Uniform-Settings + Texturen)
- Matrizen (World, View, Projection, Normal, ...)
- Renderbuffer (nicht alles geht direkt auf den Bildschirm...)

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Multithreaded Rendering
BeitragVerfasst: Sa Aug 11, 2012 12:19 
Offline
DGL Member

Registriert: Sa Mär 14, 2009 17:48
Beiträge: 99
Programmiersprache: D, Java, C++
Hi,
schonmal gut zu hören das ich in die richtige Richtung gedacht hab, deine Idee scheint auch vernünftig, sind nur einige entscheidende Detailfragen die mir noch bleiben, und zwar sagtest du, dass ein RenderObjekt folgendes kennen sollte:

Coolcat hat geschrieben:
- Vertexbuffer (und ggf. Indexbuffer)
- Shader
- Material (Uniform-Settings + Texturen)
- Matrizen (World, View, Projection, Normal, ...)
- Renderbuffer (nicht alles geht direkt auf den Bildschirm...)


Das Problem ist nur, wie kriege ich den RenderThread dazu genau diese Dinge zu erstellen? Wenn ich nur RenderObjekte habe müsste ich ja beim Execute eines jeden RenderObjektes folgendes machen:

Code:
  1. if (vertexBuffer == null) {
  2. // vertexBuffer erstellen
  3. }
  4. if (indexBuffer == null) {
  5. // ...
  6. }
  7. .
  8. .
  9. .


Sonst hätte ich ja garkeine Gelegenheit diese Sachen im RenderThread auszuführen. Vielleicht müsste der RenderThread mehrere Queues haben. Eine für initialisierungs Dinge wie VertexBuffer, Texturen, Renderbuffer, ... und eine zum Rendern selbst.

Ich werde das mal probieren. Für weitere Vorschläge und/oder Verbesserungsvorschläge/Diskussionen bin ich jederzeit offen :-).


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Multithreaded Rendering
BeitragVerfasst: Sa Aug 11, 2012 12:49 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Ich sehe da jetzt nicht so das Problem, wenn du zwei bis drei gl-Calls in so einer Execute-Methode hast. So teuer ist ein Methodencall auch nicht, vorallem nicht auf 64-bit Architekturen.

grüße

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Multithreaded Rendering
BeitragVerfasst: Sa Aug 11, 2012 12:57 
Offline
DGL Member

Registriert: Sa Mär 14, 2009 17:48
Beiträge: 99
Programmiersprache: D, Java, C++
Es hängt ja noch mehr dran als der Methoden Aufruf. Ich arbeite mit Java (DalvikVM, Android). Ich muss für jeden Job auch ein Objekt erstellen und eventuell recyclen um den Garbage Collector zu vermeiden, vom Grundsatz her fand ich die Lösung schon ganz in Ordnung, es kommt dann halt nur wirklich eine ganze Menge zusammen. Ich habe versucht mir anzugucken wie andere "Game Engines" (jMonkeyEngine, OGRE, ...) das handhaben, ist aber nicht immer so leicht in den Code einzusteigen. Ich dachte mir vielleicht geht es auf dem Weg des Forums schneller und kann ein par interessante Diskussionen in Gang setzen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Multithreaded Rendering
BeitragVerfasst: Sa Aug 11, 2012 13:05 
Offline
DGL Member
Benutzeravatar

Registriert: Di Apr 29, 2008 18:56
Beiträge: 1213
Programmiersprache: Delphi/FPC
Hey,

wir haben das bei unserem Projekt so geplant: Es gibt 2 Schritte Rendern und Update. Das Update läuft parallel in meheren Threads, sobald alle Update-Threads einmal durch sind, wird der Render-Thread gestartet und rendert die Objekte.
Vorteile: man muss die Daten nicht doppelt halten und kann die vorhandene Klassenstruktur fast 1zu1 übernehmen (wenn man denn schon eine hat). Außerdem finde ich persönlich, es ist einfacher als einen Update und einen Render-Thread zu synchronisieren.
Nachteile: ist vlt nicht ganz so schnell wie ein Render-und ein Update-Thread.

MfG Bergmann.

_________________
Aktuelle Projekte: BumpMapGenerator, Massive Universe Online
Auf meiner Homepage gibt auch noch paar Projekte und Infos von mir.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Multithreaded Rendering
BeitragVerfasst: Sa Aug 11, 2012 13:15 
Offline
DGL Member

Registriert: Sa Mär 14, 2009 17:48
Beiträge: 99
Programmiersprache: D, Java, C++
Das geht ja dann eher in die Richtung ein Thread für alles. Also du zeichnest tatsächlich erst wenn ein Update durch ist genau einen Frame. Dann kannst du den Update Thread aber falls das Zeichnen zu lange dauert nicht oder nur schwer schneller laufen lassen (für Physik und Co).
Ich möchte ja tatsächlich die Frames vorberechnen lassen und dem Renderthread dann soviel Zeit geben, wie er eben braucht. Wenn der Update Thread (bzw. die Update Threads, dass sind auch mehrere in meinem Fall) schneller ist zeichnet der Render Thread eben immer nur den aktuellsten Frame und verwirft die alten. So hatte ich mir das zumindest überlegt :-).


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Multithreaded Rendering
BeitragVerfasst: So Aug 12, 2012 11:14 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Zitat:
Sonst hätte ich ja garkeine Gelegenheit diese Sachen im RenderThread auszuführen.

Solche Dinge machst du üblicherweise beim Laden des Levels etc., nicht während das Spiel läuft.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Multithreaded Rendering
BeitragVerfasst: So Aug 12, 2012 12:08 
Offline
DGL Member

Registriert: Sa Mär 14, 2009 17:48
Beiträge: 99
Programmiersprache: D, Java, C++
Das ist richtig, aber ich lade das Level ja nicht im Renderthread, also muss ich die Informationen vom Laden bzw. die Aufgaben für den Renderthread ja irgendwie dort platzieren.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Multithreaded Rendering
BeitragVerfasst: So Aug 12, 2012 14:03 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jul 15, 2009 20:48
Beiträge: 111
Wohnort: Berlin
Programmiersprache: Delphi,JS,PHP,AS3,C#
ich ahbe keine ahnung von threads. ich hörte, es gibt probleme wenn man von mehreren threads auf den gleichen ogl context zugreift. zählt die standart-delphi-form als eigener thread? kann ich nicht dort mein level laden etc, und der renderthread verwertet einfach nur die daten? das stell ich mir als eine der aussschlaggebendsten performance boosts vor.

edit2: andererseits, angenommen der renderthread läuft zb doppelt so schnell wie der update threat, habe ich am ende doch eher weniger echte frames (ein anderes bild als zuvor) als ohne .. oO wenn ich einfach nacheinander .render und . update aufrufe, kricht jeder teil seinen perfekten anteil an rechenleistung. vill wären performance boosts möglich, wenn man noch andere sachen als reines rendering auf der gpu ausführt.

edit: sonst müsste es doch möglich sein, vom renderthread funktionen aus dem kontext-erstellenden objekt (zb TEngine) aufzurufen; um so das problem zu umgehen.

das ganze verwirrt mich. gibts dazu irgendwo etwas gutes zu lesen?

_________________
thanks to the internet we have rule 34, wich states that if something exists, theres a pornographic version of it,


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Multithreaded Rendering
BeitragVerfasst: So Aug 12, 2012 15:03 
Offline
Compliance Officer
Benutzeravatar

Registriert: So Aug 08, 2010 08:37
Beiträge: 460
Programmiersprache: C / C++ / Lua
http://wiki.delphigl.com/index.php/Tutorial_Multithreading

da steht alles wichtige drin...

_________________
offizieller DGL Compliance Beauftragter
Never run a changing system! (oder so)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Multithreaded Rendering
BeitragVerfasst: So Aug 12, 2012 15:04 
Offline
DGL Member
Benutzeravatar

Registriert: Di Apr 29, 2008 18:56
Beiträge: 1213
Programmiersprache: Delphi/FPC
Hey,

der RenderKontext muss nicht im Thread erstellt werden. Es kommt bei der Verwendung meherer Threads nur zu Problemen, da die OpenGL Befehle wild durcheinander gewürfelt werden, wenn die Threads parallel ausgeführt werden. Kleines Beispiel: Thread 1 soll ein Quad rendern:
Code:
  1. glBegin(GL_QUAD);
  2.   glVertex2f(-1, -1);
  3.   glVertex2f(-1,  1);
  4.   glVertex2f( 1,  1);
  5.   glVertex2f( 1, -1);
  6. glEnd;

Und Thread 2 soll ein Triangle rendern:
Code:
  1. glBegin(GL_TRIANGLE);
  2.   glVertex2f( 1,  0);
  3.   glVertex2f(-1,  0);
  4.   glVertex2f( 0,  2);
  5. glEnd;

Angenommen die Treads können jeweils abwechselnd eine Zeile ausführen. Dann würden folgende Aufrufe an OpenGL übergeben:
Code:
  1.  
  2. glBegin(GL_QUAD);  //1
  3. glBegin(GL_TRIANGLE); //2
  4.   glVertex2f(-1, -1); //1
  5.   glVertex2f( 1,  0); //2
  6.   glVertex2f(-1,  1); //1
  7.   glVertex2f(-1,  0); //2
  8.   glVertex2f( 1,  1); //1
  9.   glVertex2f( 0,  2); //2
  10.   glVertex2f( 1, -1); //1
  11. glEnd; //2
  12. glEnd; //1

Kommt also nur Mist raus. Den Update-Thread und den Render-Thread nacheinander aufzurufen bringt keinen Vorteil, da hier keine parallelen Aufgaben ausgeführt werden. Es würde einen Performancevorteil mit sich bringen, wenn es mehrere Update-Threads geben würde, so wie ich das oben schon beschrieben hab.
Den Render- und Update-Thread muss man natürlich auch noch etwas synchronisieren. Um dein Bsp. aufzugreifen, wenn der RenderThread doppelt so schnell ist wie der UpdateThread: Man sagt dem RenderThread einfach, wann es neue Daten gibt, wenn es keine gibt, wird auch kein Bild gerendert. So einfach ist das alles gar nicht, deshalb hat Skeptiker die Diskussion auch begonnen. Wenn du bis jetzt noch nie mit Threads gearbeitet hast, dann solltest du dir erstmal ein paar einfache Beispiele ansehen, eh du dich gleich mit Threads und OpenGL auseinander setzt.

MfG Bergmann.

_________________
Aktuelle Projekte: BumpMapGenerator, Massive Universe Online
Auf meiner Homepage gibt auch noch paar Projekte und Infos von mir.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Multithreaded Rendering
BeitragVerfasst: So Aug 12, 2012 19:32 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
@sirrk:
Zitat:
zählt die standart-delphi-form als eigener thread?

Wenn deine Anwendung nicht explizit weitere Threads startet läuft alles in einem einzigen Thread. Für ernsthafte Anwendungen sollte man zumindest immer File I/O und Netzwerk in eigene Threads auslagern. Anderenfalls muss deine Anwendung nämlich warten bis die Antwort von Festplatte oder Netzwerk kommt, insbesondere im Netzwerk kann das durchaus im Bereich von Sekunden liegen in dem deine Anwendung sonst einfach nur schlafen würde.

Zitat:
oO wenn ich einfach nacheinander .render und . update aufrufe, kricht jeder teil seinen perfekten anteil an rechenleistung.

Nein, den rendern auf der Grafikkarte heißt die CPU muss warten bis die GPU fertig ist. Das gilt insbesondere dann wenn du das Render-Ergebnis wieder für deine Anwendung brauchst. Klassisches Beispiel wäre z.B. Color-Picking. In der Zeit kannst du (mit Hilfe eines anderen Threads) wunderbar schon mal Update() für das nächste Frame berechnen. Wenn du mehrere CPU-Kerne hast ist der Nutzen natürlich noch offensichtlicher.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Multithreaded Rendering
BeitragVerfasst: Mo Aug 13, 2012 08:53 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Nov 08, 2010 18:41
Beiträge: 769
Programmiersprache: Gestern
Beim Multithreading gibts keinen goldenen Weg an sich, du musst immer selber schauen was gerade wo benötigt wird. Am besten man schnappt sich dafür
einen Profiler und kuckt nach welche Funktionen optimiert werden können. Nehmen wir z.B. mal Deluxemapping, hier stellt sich einzig die Frage ob man so viele
Oberflächen hat das man nur das Culling Optimieren kann.

_________________
Meine Homepage


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Multithreaded Rendering
BeitragVerfasst: Mo Aug 13, 2012 08:54 
Offline
DGL Member
Benutzeravatar

Registriert: Di Mai 18, 2004 16:45
Beiträge: 2621
Wohnort: Berlin
Programmiersprache: Go, C/C++
Ich kenne 2 größere Engines, da gibt es ein renderthread, der mit einer fixen fps läuft und bekommt nur durch die job-queue informationen. Die komplexität des renderthreads ist sehr trivial, überwiegend wrapping von d3d und ogl calls von einer message.
Um zu vermeiden, dass der renderthread messages mit in den nächsten frame nimmt, macht man begin-end für ein Frame. Das ist nicht verwunderlich, da die d3d Api genau das gleiche macht, wobei man das BeginFrame leer bleiben kann und EndFrame enthält das swap buffer.
Nun kommt es zur würze des systems, soll beginframe blocken, wenn endframe noch nicht unlocked hat oder soll man queries absetzen, ob schon alles fertig ist.
Ich bin für polling, da es auf neueren machienen besser skalieren wird, wenn man noch cpu zeit in irgendwas steckt, z.b. physik, ai, sound, io und so weiter.

Der render thread sollte nicht mehr als die renderapi und die reinkommenden messages kennen. Laden von meshes, texturen und so weiter ist nicht seine aufgabe, das soll der game code ausserhalb machen. Die aufgabe ist es die reinkommenden Daten auf die gpu zu laden, indem entsprechende objekte erstellt werden.

Das laden von Texturen und meshes kannst du entwerder in ein threadpool lagern oder async calls verwenden und den vorteil haben, dass es im threadpool vom kernel gehandhabt wird.
Ich empfehle 2., da es 100% schneller und bugfreier ist als der eigene threadpool.

Sound, maus und keyboard sind auch kategorie io und sollten entsprechend in eigenen threads laufen, wie rendering. Bei Maus und keyboard ist es auch geschmackssache, ob man den aktuellen status abfragt oder die message loop für das fenster verwendet.
Ich präferiere die message loop in einem thread aber das beduetet bidirektionale kommunikation, onpaint muss ein refresh im renderer auslösen, onresize den context anpassen und so weiter.
Sound braucht sein thread, damit es kein tonausfall gibt, wenn man mal etwas länger für ai oder so braucht.

_________________
"Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren"
Benjamin Franklin

Projekte: https://github.com/tak2004


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


Wer ist online?

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.

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