Asynchrone Programmierung (DirectX und C++)
In diesem Thema werden verschiedene Punkte behandelt, die Sie berücksichtigen sollten, wenn Sie asynchrone Programmierung und Threading mit DirectX verwenden.
Asynchrone Programmierung und DirectX
Wenn Sie gerade mehr über DirectX erfahren oder sogar, wenn Sie damit vertraut sind, sollten Sie in Betracht ziehen, alle Ihre Grafikverarbeitungspipeline in einem Thread zu platzieren. In jeder bestimmten Szene in einem Spiel gibt es allgemeine Ressourcen wie Bitmaps, Shader und andere Ressourcen, die exklusiven Zugriff erfordern. Diese Ressourcen erfordern, dass Sie den Zugriff auf diese Ressourcen über die parallelen Threads hinweg synchronisieren. Das Rendern ist ein schwieriger Prozess, der über mehrere Threads parallelisiert werden kann.
Wenn Ihr Spiel jedoch ausreichend komplex ist oder Sie eine verbesserte Leistung erzielen möchten, können Sie die asynchrone Programmierung verwenden, um einige der Komponenten zu parallelisieren, die nicht für Ihre Renderingpipeline spezifisch sind. Moderne Hardware verfügt über mehrere Kern- und Hyperthread-CPUs, und Ihre App sollte dies nutzen! Sie können dies sicherstellen, indem Sie eine asynchrone Programmierung für einige der Komponenten Ihres Spiels verwenden, die keinen direkten Zugriff auf den Direct3D-Gerätekontext benötigen, z. B.:
- Datei-E/A
- Physische Effekte
- KI
- networking
- audio
- controls
- XAML-basierte UI-Komponenten
Ihre App kann diese Komponenten in mehreren gleichzeitigen Threads verarbeiten. Datei-E/A, insbesondere beim Laden von Ressourcen, profitiert stark vom asynchronen Laden, da ihr Spiel oder Ihre App in einem interaktiven Zustand sein kann, während mehrere (oder mehrere hundert) Megabyte von Ressourcen geladen oder gestreamt werden. Die einfachste Möglichkeit zum Erstellen und Verwalten dieser Threads ist die Verwendung der Parallel Patterns Library und des Aufgabenmusters , wie im in PPLTasks.h definierten Parallelitätsnamespace enthalten. Die Verwendung der Parallel Patterns Library nutzt direkte Vorteile von mehreren Kern- und Hyperthread-CPUs und kann alles von wahrgenommenen Ladezeiten bis hin zu den Treffern und Verzögerungen verbessern, die mit intensiven CPU-Berechnungen oder Netzwerkverarbeitungen enthalten sind.
Hinweis In einer Universelle Windows-Plattform-App (UWP) wird die Benutzeroberfläche vollständig in einem Singlethread-Apartment (STA) ausgeführt. Wenn Sie eine Benutzeroberfläche für Ihr DirectX-Spiel mit XAML-Interoperabilität erstellen, können Sie nur mithilfe des STA auf die Steuerelemente zugreifen.
Multithreading mit Direct3D-Geräten
Multithreading für Gerätekontexte ist nur auf Grafikgeräten verfügbar, die eine Direct3D-Featureebene von 11_0 oder höher unterstützen. Sie können jedoch die Nutzung der leistungsstarken GPU auf vielen Plattformen maximieren, z. B. dedizierte Spieleplattformen. Im einfachsten Fall sollten Sie das Rendern einer HUD-Überlagerung (Heads-up Display) vom Rendern und Projizieren der 3D-Szene trennen und beide Komponenten separate parallele Pipelines verwenden. Beide Threads müssen denselben ID3D11DeviceContext verwenden, um die Ressourcenobjekte zu erstellen und zu verwalten (die Texturen, Gitter, Shader und andere Ressourcen), was jedoch singlethreaded ist und erfordert, dass Sie eine Art von Synchronisierungsmechanismus (z. B. kritische Abschnitte) implementieren, um sicher darauf zuzugreifen. Sie können zwar separate Befehlslisten für den Gerätekontext in verschiedenen Threads (für verzögertes Rendering) erstellen, aber sie können diese Befehlslisten nicht gleichzeitig in derselben ID3D11DeviceContext-Instanz wiedergeben.
Jetzt kann Ihre App auch ID3D11Device verwenden, die für Multithreading sicher ist, um Ressourcenobjekte zu erstellen. Warum also nicht immer ID3D11Device anstelle von ID3D11DeviceContext verwenden? Nun, derzeit ist die Treiberunterstützung für Multithreading für einige Grafikschnittstellen möglicherweise nicht verfügbar. Sie können das Gerät abfragen und herausfinden, ob es Multithreading unterstützt, aber wenn Sie die größtmögliche Zielgruppe erreichen möchten, können Sie mit singlethreaded ID3D11DeviceContext für die Verwaltung von Ressourcenobjekten bleiben. Das heißt, wenn der Grafikgerätetreiber Multithreading oder Befehlslisten nicht unterstützt, versucht Direct3D 11, synchronisierten Zugriff auf den Gerätekontext intern zu behandeln; und wenn Befehlslisten nicht unterstützt werden, stellt sie eine Softwareimplementierung bereit. Daher können Sie Multithreadcode schreiben, der auf Plattformen mit Grafikschnittstellen ausgeführt wird, die keine Treiberunterstützung für den Multithread-Gerätekontextzugriff haben.
Wenn Ihre App separate Threads für die Verarbeitung von Befehlslisten und für die Anzeige von Frames unterstützt, möchten Sie die GPU wahrscheinlich aktiv halten, die Befehlslisten verarbeiten, während Sie Frames zeitnah anzeigen, ohne erkennbare Stutter oder Verzögerungen anzuzeigen. In diesem Fall können Sie für jeden Thread einen separaten ID3D11DeviceContext verwenden und Ressourcen (z. B. Texturen) freigeben, indem Sie sie mit dem flag D3D11_RESOURCE_MISC_SHARED erstellen. In diesem Szenario muss ID3D11DeviceContext::Flush für den Verarbeitungsthread aufgerufen werden, um die Ausführung der Befehlsliste abzuschließen, bevor die Ergebnisse der Verarbeitung des Ressourcenobjekts im Anzeigethread angezeigt werden.
Verzögertes Rendering
Beim verzögerten Rendering werden Grafikbefehle in einer Befehlsliste aufgezeichnet, sodass sie zu einem anderen Zeitpunkt wiedergegeben werden können und das Rendern in einem Thread während der Aufzeichnung von Befehlen zum Rendern in zusätzlichen Threads unterstützt werden. Nach Abschluss dieser Befehle können sie im Thread ausgeführt werden, der das endgültige Anzeigeobjekt generiert (Framepuffer, Textur oder andere Grafikausgabe).
Erstellen Sie einen verzögerten Kontext mithilfe von ID3D11Device::CreateDeferredContext (anstelle von D3D11CreateDevice oder D3D11CreateDeviceAndSwapChain, der einen unmittelbaren Kontext erstellt). Weitere Informationen finden Sie unter "Sofortiges und verzögertes Rendering".
Zugehörige Themen