Freigeben über


Speicherverwaltungsstrategien

Ein Speicher-Manager für Direct3D 12 könnte sehr kompliziert mit allen verschiedenen Unterstützungsebenen, für UMA- oder diskrete (nicht UMA)-Adapter und mit einer beträchtlichen Palette von Architekturunterschieden zwischen GPU-Adaptern werden.

Die in diesem Abschnitt beschriebene empfohlene Strategie für die Direct3D 12-Speicherverwaltung lautet "Klassifizieren, Budget und Stream".

Ressourcentypen

Das grundlegende Konzept einer "zugesicherten Ressource" (das Erstellen von virtuellen und physischen Adressräumen, die im verwalteten physischen Speicher initialisiert werden) ist seit Direct3D 9 vorhanden, obwohl die virtuelle Adressierung (VA) und die physische Adressierung in Direct3D 12 getrennt werden können, damit die App den physischen Speicher sorgfältig verwalten kann.

Zusätzlich zu zugesicherten Ressourcen ermöglicht das Heap-Konstrukt von Direct3D 12 zwei andere Ressourcentypen: "platziert" und "reserviert". In Direct3D 11 wurde eine "reservierte" Ressource als "nebeneinander angeordnete Ressource" bezeichnet.

Reservierte Ressourcen unterscheiden sich von den platzierten Ressourcen, in denen reservierte Ressourcen über einen eigenen eindeutigen virtuellen GPU-Adressraum verfügen. Dies ermöglicht eine große Zuordnung von VA-Speicherplatz im Vorfeld und ermöglicht dann die Zuordnung von VA-Seiten zu bestimmten Abschnitten des Heaps später, und die Anwendung konfiguriert die Anordnung dynamisch neu. Der VA-Bereich ist zusammenhängend und kann sparsam zugeordnet werden.

Die reservierte Ressource kann auf Regionen im Heap mit API-Aufrufen wie UpdateTileMappings verwiesen werden, und sie können von der App resident gemacht werden, indem Seitentabellen im Flug aktualisiert werden. Wenn ein VA-Bereich NULL oder einem nicht residenten Heap zugeordnet ist, wird dieser Teil der Ressource als nicht-resident betrachtet. Wenn ein VA-Bereich einem residenten Heap zugeordnet wird, wird dieser Teil der Ressource als resident betrachtet. Heaps sind auf der Schöpfung ansässig.

Platzierte Ressourcen sind ein viel einfacheres Design, das einfach ein Zeiger auf einen bestimmten Bereich eines Heaps ist (z. B. ein 1Mb-Bereich für eine Textur in einem 5Mb-Heap). Aliasing-Barrieren ermöglichen die Verwendung überlappender platzierter Ressourcen (siehe CreatePlacedResource- und ResourceBarrier-).

Reservierte Ressourcen sind nicht auf allen Direct3D 12-Hardware verfügbar, und platzierte Ressourcen sind ein vernünftiger Fallback, obwohl platzierte Ressourcen zusammenhängend sein müssen und nicht teilweise ansässig sein müssen.

Speicherbudget

Wenn Sie in Direct3D 12 einen Heap zuordnen, erstellen Sie den physischen Speicheraspekt einer zugesicherten Ressource. Explizitere Speichersegmentauswahl ist in Direct3D 12 verfügbar (Wählen zwischen Video- und Systemspeicher). UMA-Adapter verfügen nur über ein einzelnes Speichersegment, Systemspeicher.

GPUs unterstützen seitenfehler nicht, daher müssen Entwickler sich bewusst sein, dass sie keinen Commit überschreiben, insbesondere für Systeme mit nur 1 GB Systemspeicher. Wenn eine App einen Commit übernimmt, verwendet das Betriebssystem die Planung von Prozessen mit groberer Ausrichtung, indem sie den physischen Speicher benötigen. Der Scheduler fixiert Vordergrundprozesse und übergibt im Wesentlichen einige davon, um einen Hintergrundprozess zu erstellen, der ausgeführt werden soll. Der verfügbare physische Arbeitsspeicher kann erheblich variieren, je nachdem, was der Benutzer im Hintergrund ausführt (z. B. einen Browser ausführen oder ein Video ansehen).

Die API für das Speicherbudget ist QueryVideoMemoryInfo. Bei diskreten Adaptern ist "lokal" der Videospeicher, "nicht lokal" der Systemspeicher. Bei UMA-Adaptern ist nicht lokal immer Null. Eine Designfrage ist, ob Ihr Modul sowohl Budgets als auch nur das lokale Budget verwaltet. Die Verwaltung des lokalen Budgets ist einfacher, hat jedoch einige Vorbehalte; Angenommen, es gibt ein maximales lokales Budget von 1Gb, dann kommen alle Heaps von diesem 1Gb in einem UMA-System und es gibt keinen Überlauf zum Systemspeicher (klar, da keine vorhanden ist).

Da der von Direct3D11 verwaltete Speicher für Anwendungen verwaltet wurde, würden nicht verwendete Ressourcen im Wesentlichen ausgelagert.

Wählen Sie die am besten geeigneten Ressourcenabmessungen aus. Überlegen Sie, ob die Größe einer Ressource für die Situation geeignet ist, in der die Anwendung tatsächlich ausgeführt wird. Einige Benutzer können die Anwendung in einem Fenster oder mit einer Bildschirmauflösung von 800x600 ausführen.

Klassifizierungsstrategie

Um Ressourcen in speichergebundenen Szenarien effektiv zu verwalten, sollten Sie Ressourcen wie folgt klassifizieren:

Klassifikation Beispiele Objekte und API-Features Verwaltungsnotizen
Kritisch Spiel-UI Befehlsverknäufer, Befehlswarteschlangen, Abfrage heaps, Ressourcen und Ressourcen heaps. Diese Elemente sollten im nicht ausgelagerten/immer zugesicherten Speicher gespeichert werden.
Skaliert/ optional Levelspezifische Modelle und Texturen, Swapchains, Sky boxes, First-Person Player-Charaktermodelle Ressourcen und Heaps. Zugesicherte Ressourcen, aber auch platzierte und reservierte Ressourcen funktionieren möglicherweise genauso gut. Integrieren Sie Speicher-Residency-Budgetierung in die Renderingalgorithmen. Wählen Sie die entsprechende Ebene der verfügbaren Details aus, und bewerten Sie weniger als einmal pro Frame. Techniken umfassen die Verwendung von Ressourcen mit variabler Größe und Swapchainskalierung.
Wiederverwendete Ressourcen Schattenpuffer, verzögerte Renderingressourcen, Ressourcen nach der Verarbeitung, Beleuchtungsdatencaches Ressourcen und Heaps. Überlappende Ressourcen auf Heaps und Aliasing-Barrieren. Verwenden Sie große Ressourcen oder Heapbereiche innerhalb eines Frames wieder, um die Anforderungen für den gesamten Frame zu verringern. Verwenden Sie die Technik der Wiederverwendung von speicherinternen Frames. In Direct3D 11 konnten Anwendungen ressourcen nur mit demselben Typ und potenziell großen Dimensionen wiederverwenden. Direct3D 12-Heaps ermöglichen überlappende Ressourcen für eine viel einfachere und größere Wiederverwendung.
Streamingressourcen Terrain, Open-World Texturen und Geometrie Ressourcen und Heaps. Freethread-Erstellung, Hintergrund-CPU-Threads und Befehlswarteschlangen und Listen für Hintergrundkopien. Partielle Residency, häufig basierend auf Sichtbarkeit (unter Verwendung des Ansichts-Frustums oder der entfernungsbasierten Auswertung) und revaluieren Residency-Anforderungen für jeden Frame.
Die Technik der Verwendung einer partiellen Residency-Verwaltung pro Kachel und der Wiederverwendung zwischen Frame ist verfügbar, wenn der GPU-Adapter reservierte Ressourcen innerhalb von Heaps unterstützt.
Durch die Verwendung von Interframe-Speicher-Re-Use kann eine partielle Unterressourcenaufbewahrung erreicht werden, ist jedoch weniger optimal. Platzierte Ressourcen mit Heaps sollten ein schnelleres Recycling ermöglichen, aber zugesicherte Ressourcen können als Fallback verwendet werden.

Je mehr Anwendungen sich für die meisten Aufgaben auf Streamingressourcen bezieht, desto mehr nutzen sie platzierte und reservierte Ressourcen, wodurch die Wiederverwendung des Speichers zwischen diesen vier Klassifizierungen maximiert wird. Je mehr Anwendungen streamen, desto mehr Budget und Priorisierung der Bandbreite.

In der Regel müssen Direct3D 12-Grafikmodule ein vielfältigeres und dynamischeres Budget berücksichtigen und dies strenger tun als in der Vergangenheit. Die besten Anwendungen finden alle vier Kategorien in das Budget, das dem Prozess zugewiesen wird, und skaliert das Spiel von der mobilen Hintergrund-App auf diskrete Budgets im Vollbildmodus. Aber viele Anwendungen werden wahrscheinlich kämpfen, indem sie mit zu vielen kritischen Kategorietypen von Ressourcen beginnen. Mit Direct3D 11 können Ressourcen anonym erstellt und kritischen Status belegt werden, ohne die Leistung zu beeinträchtigen. Für Direct3D 12 müssen Entwickler jedoch sorgfältig nach zufällig erstellten Ressourcen in ihrem Modul und in der Middleware suchen und sie einer der anderen Kategorien erneut zuweisen.

Andere Problembereiche sind Middleware-Komponenten, Benutzersteuerelemente und Intraframestreaming. Middleware-Komponenten sind möglicherweise nicht für ein Budget verfügbar und müssen nicht eng zusammenarbeiten. Middleware-Komponenten könnten wahrscheinlich Features als Renderingtechniken verfügbar machen; und die Anwendung könnte sich auf die Bereitstellung von Middleware- und Moduleinstellungen verlassen. Entwickler können sich auf Direct3D 11 verlassen, um die Paging zu erledigen und die richtige Framerate zu erzielen. In einigen Fällen waren Direct3D 11-Anwendungen möglicherweise Ressourceninhalte in und aus jedem Frame auslagerungen; und dies führte zu akzeptablen Bildfrequenzen für den Benutzer. Die meisten Module streamen nur Ressourcendaten als Hintergrundaktivität, bei denen sie keinen ordnungsgemäßen Fallback auf das Intraframestreaming mit hoher Priorität aufweist. Die Engines werden aufgefordert, dies zu implementieren, was einige der CPU-Overheadgewinne beeinträchtigt, die sie suchen, indem sie zu Direct3D 12 wechseln. Modulentwickler könnten ihre Frames in Phasen aufstechen, um mehr Möglichkeiten für wiederverwendbare Ressourcen zu bieten; und arbeiten wahrscheinlich mit Middleware-Anbietern zusammen, um platzierte Ressourcen und Heaps für die erneute Verwendung des Speichers innerhalb des Frames zu unterstützen.

CreateCommittedResource-

CreateReservedResource-

Direct3D 12-Programmieranleitung

Speicherverwaltung

Ressourcenbindungs-