Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

FSA

Community-Fossil

  • »FSA« ist der Autor dieses Themas
  • Private Nachricht senden

1

16.09.2013, 18:17

Rendern mit mehreren Threads

Hallo!
Ich habe mir die letzten Tage mal Gedanken darüber gemacht, mit DirectX 11 in mehreren Threads zu rendern. Ich habe mich in das Thema DeferredContext etwas eingearbeitet und nun stellen sich folgende Fragen:
Wenn ich zwei mal ein Dreieck zeichnen möchte, zeichne ich das erste Dreieck mit dem immediate context im Hauptthread und füge das zweite Dreieck in einem anderen Thread der Befehlsliste eines DeferredContext hinzu. Nach dem Zeichnen im Hauptthread führe ich die Befehlsliste auf dem immediate context aus.
Frage 1: Woher weiß ich, dass zum Zeitpunkt der Ausführungen von der Befehlsliste die Befehlsliste überhaupt schon fertig ist?
Frage 2: Ist es nicht gleich schnell, die zwei Dreiecke direkt hintereinander mit dem immediate context zu zeichnen? Die Befehlsliste macht doch nichts anderes, oder?

Zitat

Der RCCSWU (RandomCamelCaseSomtimesWithUndersquare) Stil bricht auch mal mit den veraltet strukturierten Denkmustern und erlaubt dem Entwickler seine Kreativität zu entfalten.

2

16.09.2013, 18:59

Frage 2: Ist es nicht gleich schnell, die zwei Dreiecke direkt hintereinander mit dem immediate context zu zeichnen? Die Befehlsliste macht doch nichts anderes, oder?

Ich habe mich noch nicht eingehend mit dem Thema beschäftigt, aber:
Das Rendern beansprucht sowohl GPU als auch CPU. Die GPU ist eh massiv parallel, auf der Seite ändert sich durch mehrere Renderthreads also nichts. Was aber schneller wird ist die 'Vorverarbeitung' auf der CPU. Demnach muss die Befehlsliste gar nicht anders aussehen, sie muss nur auf CPU-Seite durch mehr Threads schneller erstellt werden.
Zu Frage 1: Nur weil der Renderaufruf ausgeführt wurde, heißt das nicht, dass schon etwas gerendert wurde. Sonst könnten CPU und GPU ja nur Abwechselng arbeiten, was Zeitverschwendung wäre. Eventuell musst du also gar nicht wissen, wann was fertig ist.
Lieber dumm fragen, als dumm bleiben!

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

3

16.09.2013, 19:49

Frage 1: Woher weiß ich, dass zum Zeitpunkt der Ausführungen von der Befehlsliste die Befehlsliste überhaupt schon fertig ist?

Falls du die Befehlsliste meinst, die im anderen Thread erzeugt wird: Das musst du natürlich irgendwie sicherstellen... ;)

Frage 2: Ist es nicht gleich schnell, die zwei Dreiecke direkt hintereinander mit dem immediate context zu zeichnen? Die Befehlsliste macht doch nichts anderes, oder?

Bei einfach nur zwei einzelnen Dreiecken ist es vermutlich sogar wesentlich schneller, einfach in den Immediate Context zu zeichnen... ;)

Direct3D ist im Prinzip nur eine sehr dünne Schicht zwischen deiner Anwendung und dem User Mode Driver (wenn man mal einen Blick in das Windows Display Driver Model wirft, fällt auf, dass das Interface zum Grafiktreiber dem von Direct3D sehr sehr ähnlich ist). Direct3D Aufrufe landen am Ende bei diesem Grafiktreiber, welcher im Prinzip nichts anderes tut, als einen sog. Command Buffer zu befüllen, welcher Instruktionen in einer für die GPU verständlichen Form enthält. Wenn das Graphics Kernel Subsystem dem Prozess deiner Anwendung das nächste Mal Zeit auf der GPU zuteilt, wird einfach über den Kernel Mode Driver der nächste fertige Command Buffer an die GPU gesendet, welche diesen dann ausführt.

Ich denk, du siehst schon, wo genau die Sache mit den "Befehlslisten" von Direct3D nun ins Bild passt. Was du damit machen kannst, ist im Prinzip den ganzen, mit dem Befüllen der Command Buffer – wenn du so willst, dem Übersetzten von Direct3D Aufrufen in GPU Instruktionen – verbundenen, CPU-seitigen Overhead auf mehrere Cores zu verteilen. Voraussetzung, damit das was bringt, ist natürlich, dass dieser Overhead in deiner Anwendung tatsächlich von belangen ist. Wenn du nur zwei Dreiecke malst, wird der, allein der Verwendung mehrerer Threads und Deferred Contexts etc. entspringende, Overhead alles, was du dadurch jemals sparen könntest, vermutlich um ein Vielfaches übersteigen...

Auch sollte man bedenken, dass der Grafiktreiber dieses Feature unterstützen muss, denn ansonsten wird es von der Direct3D Runtime emuliert, was den potentiellen Gewinn vermutlich nochmal bedeutend schmälert. Ich hab grad keinen Caps Viewer zur Hand, aber als ich das letzte Mal nachgeschaut hab, hatten weder NVIDIA noch AMD Driver Support dafür...

Edit: Hab grad nachgeschaut; NVIDIA scheint Command Lists mittlerweile zu unterstützen, AMD, zumindest mit dem über Windows Update gelieferten Driver auf meinem Laptop, nicht...

Dieser Beitrag wurde bereits 7 mal editiert, zuletzt von »dot« (16.09.2013, 21:16)


FSA

Community-Fossil

  • »FSA« ist der Autor dieses Themas
  • Private Nachricht senden

4

16.09.2013, 20:37

Also ist der deferred context bzw die Befehlsliste nur eine Hilfe zum Abwälzen von CPU Overhead auf mehrere Threads?

Zitat

Der RCCSWU (RandomCamelCaseSomtimesWithUndersquare) Stil bricht auch mal mit den veraltet strukturierten Denkmustern und erlaubt dem Entwickler seine Kreativität zu entfalten.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

5

16.09.2013, 20:43

Ganz genau

FSA

Community-Fossil

  • »FSA« ist der Autor dieses Themas
  • Private Nachricht senden

6

16.09.2013, 20:51

Gut danke!

Zitat

Der RCCSWU (RandomCamelCaseSomtimesWithUndersquare) Stil bricht auch mal mit den veraltet strukturierten Denkmustern und erlaubt dem Entwickler seine Kreativität zu entfalten.

FSA

Community-Fossil

  • »FSA« ist der Autor dieses Themas
  • Private Nachricht senden

7

20.09.2013, 22:53

Wenn mein Programm bereit ist, eine (vorher erstellte) Befehlsliste auszuführen, aber die Befehlsliste noch nicht vollständig fertig ist, sollte ich dann ein Konstrukt in der Art in meinem Main-Thread benutzen?

C-/C++-Quelltext

1
2
3
4
while(!bFinish)
{}

Befehlsliste->Rendern();

Zitat

Der RCCSWU (RandomCamelCaseSomtimesWithUndersquare) Stil bricht auch mal mit den veraltet strukturierten Denkmustern und erlaubt dem Entwickler seine Kreativität zu entfalten.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

8

20.09.2013, 23:04

Das allein bringt keine korrete Synchronisation. Du könntest eine std::condition_variable oder ein Win32 Event verwenden. Wenn du bei deiner Schleife bleiben willst, solltest du zumindest einen std::atomic<bool> verwenden.

Legend

Alter Hase

Beiträge: 731

Beruf: Softwareentwickler

  • Private Nachricht senden

9

21.09.2013, 12:39

Auf jeden Fall würde diese Schleife in der Zeit einen CPU Kern zum Glühen bringen. o_O ;)
Noch ein Grund für etwas ausgefeilteres. Auch wenn die Konstruktion manchmal wohl sogar echte Anwendungen hat ..
"Wir müssen uns auf unsere Kernkompetenzen konzentrieren!" - "Juhu, wir machen eine Farm auf!"

Netzwerkbibliothek von mir, C#, LGPL: https://sourceforge.net/projects/statetransmitt/

FSA

Community-Fossil

  • »FSA« ist der Autor dieses Themas
  • Private Nachricht senden

10

22.09.2013, 15:12

Ja das habe ich eben auch herausgefunden.
Dann stellt sich mir mal wieder eine neue Frage. Wenn ich eine Variable im Shader setzen will (ID3DX11EffectVariable) pCam->SetRawValue(&Vector4(g_pCamera->GetPosition(), 1.0f), 0, sizeof(Vector4)); sollte ich diesen Abschnitt doch mit einem Mutex sperren. Es kann ja von zwei Threads gleichzeitig die Variable gesetzt werden. Schreibt die Befehlsliste denn auch die Änderungen einer Variable im Shader mit? Was bringen mir dann mehrere Threads wenn ich alle Threads blockieren muss, bis der eine Fertig ist mit Rendern bzw. mit befüllen der Befehlsliste?

Zitat

Der RCCSWU (RandomCamelCaseSomtimesWithUndersquare) Stil bricht auch mal mit den veraltet strukturierten Denkmustern und erlaubt dem Entwickler seine Kreativität zu entfalten.

Werbeanzeige