Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Verwendungskennzeichnungen geben an, wie die Anwendung die Ressourcendaten verwenden möchte, um Ressourcen im leistungsstärksten Speicherbereich zu platzieren. Ressourcendaten werden über Ressourcen hinweg kopiert, sodass die CPU oder GPU ohne Auswirkungen auf die Leistung darauf zugreifen kann.
Es ist nicht erforderlich, ressourcen als im Videospeicher oder im Systemspeicher zu erstellen, oder um zu entscheiden, ob die Laufzeit den Speicher verwalten soll. Mit der Architektur des WDDM (Windows Display Driver Model) erstellen Anwendungen Direct3D-Ressourcen mit unterschiedlichen Verwendungskennzeichnungen, um anzugeben, wie die Anwendung die Ressourcendaten verwenden möchte. Dieses Treibermodell virtualisiert den von Ressourcen verwendeten Arbeitsspeicher; es liegt in der Verantwortung des Betriebssystems/Treibers/Speicher-Managers, Ressourcen entsprechend der erwarteten Nutzung im performantesten Bereich des Speichers zu platzieren.
Der Standardfall ist, dass Ressourcen für die GPU verfügbar sind. Es gibt Zeiten, in denen die Ressourcendaten für die CPU verfügbar sein müssen. Das Kopieren von Ressourcendaten, damit der entsprechende Prozessor darauf zugreifen kann, ohne dass die Leistung beeinträchtigt wird, erfordert einige Kenntnisse darüber, wie die API-Methoden funktionieren.
Kopieren von Ressourcendaten
Ressourcen werden im Arbeitsspeicher erstellt, wenn Direct3D einen Create-Aufruf ausführt. Sie können im Videospeicher, im Systemspeicher oder in anderen Speicherarten erstellt werden. Da das WDDM-Treibermodell diesen Speicher virtualisiert, müssen Anwendungen nicht mehr nachverfolgen, in welcher Art von Speicherressourcen erstellt werden.
Im Idealfall befinden sich alle Ressourcen im Videospeicher, sodass die GPU sofortigen Zugriff darauf haben kann. Es ist jedoch manchmal erforderlich, dass die CPU die Ressourcendaten liest oder die GPU auf Ressourcendaten zugreifen kann, in die die CPU geschrieben hat. Direct3D behandelt diese verschiedenen Szenarien, indem sie die Anwendung auffordert, eine Verwendung anzugeben, und bietet dann bei Bedarf mehrere Methoden zum Kopieren von Ressourcendaten.
Je nachdem, wie die Ressource erstellt wurde, ist es nicht immer möglich, direkt auf die zugrunde liegenden Daten zuzugreifen. Dies kann bedeuten, dass die Ressourcendaten aus der Quellressource in eine andere Ressource kopiert werden müssen, auf die der entsprechende Prozessor zugreifen kann. In Bezug auf Direct3D kann direkt über die GPU auf Standardressourcen zugegriffen werden, auf dynamische Ressourcen und Stagingressourcen kann direkt von der CPU zugegriffen werden.
Nachdem eine Ressource erstellt wurde, kann die Verwendung nicht mehr geändert werden. Kopieren Sie stattdessen den Inhalt einer Ressource in eine andere Ressource, die mit einer anderen Verwendung erstellt wurde. Sie kopieren Ressourcendaten aus einer Ressource in eine andere, oder kopieren Sie Daten aus dem Speicher in eine Ressource.
Es gibt zwei Hauptarten von Ressourcen: kartierbar und nicht kartierbar. Ressourcen, die mit dynamischen oder Staging-Verwendungen erstellt wurden, können zugeordnet werden, während Ressourcen, die mit Standard- oder unveränderlichen Verwendungen erstellt wurden, nicht zugeordnet werden können.
Das Kopieren von Daten zwischen nicht mappbaren Ressourcen erfolgt sehr schnell, da dies der häufigste Fall ist und um eine gute Leistung zu gewährleisten optimiert wurde. Da diese Ressourcen nicht direkt von der CPU zugänglich sind, sind sie optimiert, damit die GPU sie schnell bearbeiten kann.
Das Kopieren von Daten zwischen zugeordneten Ressourcen ist problematischer, weil die Leistung von der Nutzung abhängen wird, mit der die Ressource erstellt wurde. Beispielsweise kann die GPU eine dynamische Ressource relativ schnell lesen, aber nicht in sie schreiben, und die GPU kann nicht direkt in Stagingressourcen lesen oder schreiben.
Anwendungen, die Daten aus einer Ressource mit Standardnutzung in eine Ressource mit Stagingnutzung kopieren möchten (damit die CPU die Daten lesen kann – also das GPU-Rückleseproblem), müssen dies mit Bedacht tun. Siehe Zugreifen auf Ressourcendatenunten.
Zugreifen auf Ressourcendaten
Für den Zugriff auf eine Ressource ist die Zuordnung der Ressource erforderlich; Die Zuordnung bedeutet im Wesentlichen, dass die Anwendung versucht, der CPU Zugriff auf den Arbeitsspeicher zu gewähren. Der Prozess der Zuordnung einer Ressource, damit die CPU auf den zugrunde liegenden Speicher zugreifen kann, kann zu Leistungsengpässen führen. Aus diesem Grund müssen Sie sich darum kümmern, wie und wann diese Aufgabe ausgeführt werden soll.
Die Performance kann zum Stillstand kommen, wenn die Anwendung versucht, eine Ressource zum falschen Zeitpunkt zuzuordnen. Wenn die Anwendung versucht, auf die Ergebnisse eines Vorgangs zuzugreifen, bevor dieser Vorgang abgeschlossen ist, tritt ein Pipeline-Stillstand auf.
Das Ausführen eines Mapping-Vorgangs zu einem ungünstigen Zeitpunkt kann zu einem erheblichen Leistungsverlust führen, indem die GPU und die CPU gezwungen werden, sich gegenseitig zu synchronisieren. Diese Synchronisierung tritt auf, wenn die Anwendung auf eine Ressource zugreifen möchte, bevor die GPU damit fertig ist, sie in eine Ressource zu kopieren, die die CPU zuordnen kann.
Überlegungen zur Leistung
Es empfiehlt sich, einen PC als computer zu betrachten, der als parallele Architektur mit zwei Haupttypen von Prozessoren ausgeführt wird: eine oder mehrere CPU und eine oder mehrere GPUs. Wie bei jeder parallelen Architektur wird die beste Leistung erzielt, wenn jeder Prozessor mit genügend Aufgaben geplant wird, um zu verhindern, dass er im Leerlauf läuft und wenn die Arbeit eines Prozessors nicht auf die Arbeit eines anderen wartet.
Das Worst-Case-Szenario für die GPU/CPU-Parallelität ist die Notwendigkeit, dass ein Prozessor gezwungen ist, auf die Ergebnisse der Arbeit von einem anderen zu warten. Direct3D entfernt diese Kosten durch asynchron arbeitende Kopiermethoden; die Kopie wird nicht unbedingt ausgeführt, wenn die Methode zurückgegeben wird.
Der Vorteil besteht darin, dass die Anwendung die Leistungskosten des tatsächlichen Kopierens der Daten erst dann zahlt, wenn die CPU auf die Daten zugreift. Dies ist der Fall, wenn Map aufgerufen wird. Wenn die Map-Methode aufgerufen wird, nachdem die Daten tatsächlich kopiert wurden, tritt kein Leistungsverlust auf. Wenn andererseits die Map-Methode aufgerufen wird, bevor die Daten kopiert wurden, tritt ein Pipeline-Stall auf.
Asynchrone Aufrufe in Direct3D (die die überwiegende Mehrheit der Methoden und insbesondere Renderaufrufe sind) werden in einem so genannten Befehlspuffer gespeichert. Dieser Puffer ist intern beim Grafiktreiber und wird verwendet, um Aufrufe an die zugrunde liegende Hardware zu bündeln, sodass der kostspielige Wechsel vom Benutzermodus zum Kernelmodus in Microsoft Windows so selten wie möglich erfolgt.
Der Befehlspuffer wird geleert, wodurch ein Benutzer-/Kernelmoduswechsel in einem von vier Situationen wie folgt verursacht wird.
- Present wird aufgerufen.
- Flush wird aufgerufen.
- Der Befehlspuffer ist voll; seine Größe ist dynamisch und wird vom Betriebssystem und dem Grafiktreiber gesteuert.
- Die CPU erfordert Zugriff auf die Ergebnisse eines Befehls, der auf die Ausführung im Befehlspuffer wartet.
Von den oben genannten vier Situationen ist Zahl 4 die wichtigste für die Leistung. Wenn die Anwendung einen Aufruf zum Kopieren einer Ressource oder Unterressource ausgibt, wird dieser Aufruf im Befehlspuffer in die Warteschlange gestellt.
Wenn die Anwendung dann versucht, die Stagingressource zuzuordnen, die das Ziel des Kopiervorgangs war, bevor der Befehlspuffer geleert wurde, tritt eine Pipeline-Blockierung auf. Dies geschieht, weil nicht nur der Copy-Aufruf ausgeführt werden muss, sondern auch alle anderen Befehle im Befehlspuffer verarbeitet werden müssen. Dies führt dazu, dass GPU und CPU synchronisiert werden, weil die CPU darauf wartet, auf die Stagingressource zuzugreifen, während die GPU den Befehlspuffer entleert, um schließlich die Ressource zu füllen, die die CPU benötigt. Sobald die GPU die Kopie abgeschlossen hat, beginnt die CPU mit dem Zugriff auf die Stagingressource, die GPU befindet sich jedoch während dieser Zeit im Leerlauf.
Häufiges Ausführen während der Laufzeit wird die Leistung erheblich beeinträchtigen. Aus diesem Grund sollte die Zuordnung von Ressourcen, die mit der Standardverwendung erstellt wurden, sorgfältig durchgeführt werden. Die Anwendung muss lange genug warten, bis der Befehlspuffer geleert wird und somit alle diese Befehle ausgeführt werden, bevor versucht wird, die entsprechende Stagingressource zuzuordnen.
Wie lange sollte die Anwendung warten? Mindestens zwei Frames, da dadurch Parallelität zwischen den CPU(n) und der GPU maximal genutzt werden kann. Die Funktionsweise der GPU besteht darin, dass die Anwendung, während sie Frame N verarbeitet und Aufrufe an den Befehlspuffer übermittelt, die GPU währenddessen die Aufrufe aus dem vorherigen Frame N-1 ausführt.
Wenn eine Anwendung also eine Ressource zuordnen möchte, die aus dem Videospeicher stammt und eine Ressource bei Frame N kopiert, beginnt dieser Aufruf tatsächlich mit der Ausführung bei Frame N+1, wenn die Anwendung Aufrufe für den nächsten Frame sendet. Die Kopie sollte abgeschlossen sein, wenn die Anwendung Bild N+2 verarbeitet.
Rahmen | GPU/CPU-Status |
---|---|
N |
|
N+1 |
|
N+2 |
|
N+3 |
|
N+4 | ... |
Verwandte Themen