Residenz

Ein Objekt wird als resident betrachtet, wenn es für die GPU zugänglich ist.

Residenzbudget

GPUs unterstützen noch keine Seitenfehler. Daher müssen Anwendungen Daten in den physischen Arbeitsspeicher committen, während die GPU darauf zugreifen kann. Dieser Prozess wird als "Etwas resident machen" bezeichnet und muss sowohl für den physischen Systemspeicher als auch für den physischen diskreten Videospeicher durchgeführt werden. In D3D12 kapseln die meisten API-Objekte eine gewisse Menge an GPU-Zugänglichem Arbeitsspeicher. Dieser gpu-zugängliche Arbeitsspeicher wird während der Erstellung des API-Objekts als Resident festgelegt und bei der Zerstörung des API-Objekts entfernt.

Die Menge des für den Prozess verfügbaren physischen Arbeitsspeichers wird als Videospeicherbudget bezeichnet. Das Budget kann merklich schwanken, wenn Hintergrundprozesse aufwachen und schlafen. und schwanken dramatisch, wenn der Benutzer zu einer anderen Anwendung wechselt. Die Anwendung kann benachrichtigt werden, wenn sich das Budget ändert und sowohl das aktuelle Budget als auch die aktuell verbrauchte Arbeitsspeichermenge abfragen. Wenn eine Anwendung nicht innerhalb ihres Budgets bleibt, wird der Prozess zeitweilig eingefroren, damit andere Anwendungen ausgeführt werden können, und/oder die Erstellungs-APIs einen Fehler zurückgeben. Die IDXGIAdapter3-Schnittstelle stellt die Methoden für diese Funktionalität bereit, insbesondere QueryVideoMemoryInfo und RegisterVideoMemoryBudgetChangeNotificationEvent.

Anwendungen werden empfohlen, eine Reservierung zu verwenden, um die Menge an Arbeitsspeicher anzugeben, auf die sie nicht verzichten können. Im Idealfall sind die vom Benutzer angegebenen "niedrigen" Grafikeinstellungen oder etwas noch niedrigeres der richtige Wert für eine solche Reservierung. Durch das Festlegen einer Reservierung erhält eine Anwendung nie ein höheres Budget als normalerweise. Stattdessen helfen die Reservierungsinformationen dem Betriebssystemkern dabei, die Auswirkungen großer Speicherdrucksituationen schnell zu minimieren. Es ist nicht garantiert, dass die Reservierung für die Anwendung verfügbar ist, wenn die Anwendung nicht die Vordergrundanwendung ist.

Heapressourcen

Während viele API-Objekte einen Teil des GPU-zugänglichen Arbeitsspeichers kapseln, wird erwartet, dass Heapressourcen & die wichtigste Art und Weise sind, wie Anwendungen physischen Arbeitsspeicher nutzen und verwalten. Ein Heap ist die niedrigste Einheit zum Verwalten des physischen Arbeitsspeichers, daher ist es gut, mit ihren Residenzeigenschaften vertraut zu sein.

  • Heaps können nicht teilweise residiert werden, es gibt jedoch Problemumgehungen mit reservierten Ressourcen.
  • Heaps sollten als Teil eines bestimmten Pools budgetiert werden. UMA-Adapter verfügen über einen Pool, während diskrete Adapter über zwei Pools verfügen. Es ist zwar richtig, dass der Kernel einige Heaps auf diskreten Adaptern vom Videospeicher in den Systemspeicher verschieben kann, dies geschieht jedoch nur als extremes letztes Mittel. Anwendungen sollten sich nicht auf das Überbudgetverhalten des Kernels verlassen und sich stattdessen auf eine gute Budgetverwaltung konzentrieren.
  • Heaps können aus der Residenz entfernt werden, wodurch ihre Inhalte auf den Datenträger ausgelagert werden können. Die Zerstörung von Heaps ist jedoch eine zuverlässigere Technik, um die Residenz für alle Adapterarchitekturen freizugeben. Bei Adaptern, bei denen sich das Feld "MaxGPUVirtualAddressBitsPerProcess " von D3D12_FEATURE_DATA_GPU_VIRTUAL_ADDRESS_SUPPORT in der Nähe der Budgetgröße befindet, wird Evict den Wohnsitz nicht zuverlässig zurückerobern.
  • Die Heaperstellung kann langsam sein. es ist jedoch für die Hintergrundthreadverarbeitung optimiert. Es wird empfohlen, Heaps für Hintergrundthreads zu erstellen, um zu vermeiden, dass der Renderthread durchleuchtet wird. In D3D12 können mehrere Threads erstellungsroutinen gleichzeitig sicher aufrufen.

D3D12 führt mehr Flexibilität und Orthogonalität in sein Ressourcenmodell ein, um mehr Optionen für Anwendungen zu ermöglichen. Es gibt drei allgemeine Arten von Ressourcen in D3D12: committiert, platziert und reserviert.

  • Zugesagte Ressourcen erstellen gleichzeitig eine Ressource und einen Heap. Der Heap ist implizit und kann nicht direkt zugegriffen werden. Der Heap ist entsprechend groß, um die gesamte Ressource innerhalb des Heaps zu finden.
  • Platzierte Ressourcen ermöglichen die Platzierung einer Ressource bei einem Ungleich-Null-Offset innerhalb eines Heaps. Offsets müssen in der Regel auf 64 KB ausgerichtet sein. es gibt jedoch einige Ausnahmen in beide Richtungen. MSAA-Ressourcen erfordern eine Offsetausrichtung von 4 MB, und die Offsetausrichtung mit 4 KB ist für kleine Texturen verfügbar. Platzierte Ressourcen können nicht direkt auf einen anderen Heap verschoben oder neu zugeordnet werden. sie ermöglichen jedoch eine einfache Verlagerung der Ressourcendaten zwischen Heaps. Nachdem Sie eine neue platzierte Ressource in einem anderen Heap erstellt und die Ressourcendaten kopiert haben, müssen neue Ressourcendeskriptoren für den neuen Ressourcendatenspeicherort verwendet werden.
  • Reservierte Ressourcen sind nur verfügbar, wenn der Adapter gekachelte Ressourcenebene 1 oder höher unterstützt. Sofern verfügbar, bieten sie die modernsten Techniken für das Residency Management. Aber nicht alle Adapter unterstützen sie derzeit. Sie ermöglichen das Neumapping einer Ressource, ohne dass ressourcendeskriptoren, partielle mip-Level-Residenzen und Szenarien mit geringer Textur usw. neu erstellt werden müssen. Nicht alle Ressourcentypen werden unterstützt, auch wenn reservierte Ressourcen verfügbar sind, sodass ein vollständig allgemeiner seitenbasierter Residency-Manager noch nicht möglich ist.

Residenzprioritäten

Die Windows 10 Creators Update ermöglicht es Entwicklern, zu beeinflussen, welche Heaps und Ressourcen bevorzugt bleiben, wenn der Arbeitsspeicherdruck erfordert, dass einige seiner Ressourcen herabgestuft werden. Dies hilft Entwicklern, Anwendungen mit höherer Leistung zu erstellen, indem sie Wissen nutzen, das die Runtime nicht aus der API-Nutzung ableiten kann. Es wird erwartet, dass Entwickler komfortabler und fähiger werden, Prioritäten anzugeben, wenn sie von der Verwendung von commitierten Ressourcen zu neu zugewiesenen und gekachelten Ressourcen wechseln.

Die Anwendung dieser Prioritäten muss einfacher sein, als zwei dynamische Speicherbudgets zu verwalten, indem Ressourcen manuell herabgestuft und gefördert werden, da Anwendungen dies bereits tun können. Daher wird der Entwurf der API für die Residenzpriorität natürlich mit angemessenen Standardprioritäten abgestimmt, die jedem Heap oder jeder Ressource bei der Erstellung zugewiesen sind. Weitere Informationen finden Sie unter ID3D12Device1::SetResidencyPriority und die D3D12_RESIDENCY_PRIORITY-Enumeration .

Mit Prioritäten wird von Entwicklern folgendes erwartet:

  • Erhöhen Sie die Priorität einiger außergewöhnlicher Heaps, um die auswirkungen auf die Leistung dieser Heaps, die früher oder häufiger herabgestuft werden, besser zu mindern, als es ihre natürlichen Zugriffsmuster erfordern würden. Dieser Ansatz wird voraussichtlich von Anwendungen genutzt, die von Grafik-APIs wie Direct3D 11 oder OpenGL portiert werden, deren Ressourcenverwaltungsmodell sich erheblich von direct3D 12 unterscheidet.
  • Überschreiben Sie fast alle Heapprioritäten mit dem eigenen Bucketisierungsschema der Anwendung, entweder festgelegt, basierend auf den Kenntnissen des Programmierers über die Zugriffshäufigkeit oder dynamisch; ein festes Schema ist einfacher zu verwalten als ein dynamisches Schema, kann jedoch weniger effektiv sein und die Intevention des Programmierers erfordern, wenn sich die Verwendungsmuster im Laufe der Entwicklung ändern. Dieser Ansatz wird voraussichtlich von Anwendungen genutzt, die im Direct3D-12-Stil für die Ressourcenverwaltung erstellt werden, z. B. von Anwendungen, die die Residenzbibliothek verwenden (insbesondere dynamische Schemas).

Standardprioritätsalgorithmus

Eine Anwendung kann keine nützlichen Prioritäten für Heaps angeben, die sie verwalten möchte, ohne zuvor den Standardprioritätsalgorithmus zu unterschreiten. Dies liegt daran, dass der Wert der Zuweisung einer bestimmten Priorität zu einem Heap von seiner relativen Priorität zu anderen priorisierten Heaps abgeleitet wird, die um denselben Arbeitsspeicher konkurrieren.

Die zum Generieren von Standardprioritäten gewählte Strategie besteht darin, Heaps in zwei Buckets zu kategorisieren, wobei Heaps bevorzugt werden (denen eine höhere Priorität eingeräumt wird), die von der GPU häufig geschrieben werden, gegenüber Heaps, die nicht vorhanden sind.

Der Bucket mit hoher Priorität enthält Heaps und Ressourcen, die mit Flags erstellt werden, die sie als Renderziele, Tiefenschablonenpuffer oder Unordered Access Views (UAVs) identifizieren. Diesen werden Prioritätswerte im Bereich ab D3D12_RESIDENCY_PRIORITY_HIGH zugewiesen. um diese Heaps und Ressourcen weiter zu priorisieren, werden die niedrigsten 16-Bits der Priorität auf die Größe des Heaps oder der Ressource, geteilt durch 10 MB(Sättigung mit 0xFFFF für extrem große Heaps) festgelegt. Diese zusätzliche Priorisierung begünstigt größere Heaps und Ressourcen.

Der Bucket mit niedriger Priorität enthält alle anderen Heaps und Ressourcen, denen der Prioritätswert D3D12_RESIDENCY_PRIORITY_NORMAL zugewiesen wird. Es wird keine weitere Priorisierung dieser Heaps und Ressourcen versucht.

Programmierresidenzverwaltung

Einfache Anwendungen sind möglicherweise in der Lage, nur zugesagte Ressourcen zu erstellen, bis Fehler aus dem Arbeitsspeicher auftreten. Bei einem Fehler kann die Anwendung andere zugesagte Ressourcen oder API-Objekte zerstören, um weitere Ressourcenerstellungen erfolgreich zu ermöglichen. Aber auch einfache Anwendungen werden dringend empfohlen, bei negativen Budgetänderungen watch und nicht verwendete API-Objekte ungefähr einmal pro Frame zu zerstören.

Die Komplexität eines Residency Management-Designs wird steigen, wenn versucht wird, für Adapterarchitekturen zu optimieren oder Residency-Prioritäten zu integrieren. Das diskrete Budgetieren und Verwalten von zwei Pools mit diskretem Arbeitsspeicher ist komplexer als die Verwaltung nur eines, und das Zuweisen fester Prioritäten auf breiter Ebene kann zu einer Wartungslast werden, wenn sich die Nutzungsmuster weiterentwickeln. Das Überlaufen von Texturen in den Systemspeicher erhöht die Komplexität, da die falsche Ressource im Systemspeicher die Framerate stark beeinträchtigen kann. Außerdem gibt es keine einfache Funktionalität, um die Ressourcen zu identifizieren, die entweder von einer höheren GPU-Bandbreite profitieren oder eine geringere GPU-Bandbreite tolerieren würden.

Noch komplexere Designs werden die Features des aktuellen Adapters abfragen. Diese Informationen sind in D3D12_FEATURE_DATA_GPU_VIRTUAL_ADDRESS_SUPPORT, D3D12_FEATURE_DATA_ARCHITECTURE, D3D12_TILED_RESOURCES_TIER und D3D12_RESOURCE_HEAP_TIER verfügbar.

Mehrere Teile einer Anwendung werden wahrscheinlich verschiedene Techniken verwenden. Beispielsweise können einige große Texturen und selten ausgeführte Codepfade commitierte Ressourcen verwenden, während viele Texturen mit einer Streamingeigenschaft gekennzeichnet sein können und eine allgemeine Technik für platzierte Ressourcen verwenden.

ID3D12Heap

Speicherverwaltung