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.
Genau wie bei Direct3D 12 muss Ihre DirectML-Anwendung (um nicht definiertes Verhalten zu vermeiden) objektlebensdauern und die Synchronisierung zwischen der CPU und der GPU ordnungsgemäß verwalten. DirectML folgt einem identischen Ressourcenlebensdauermodell mit direct3D 12.
- Lebensdauerabhängigkeiten zwischen zwei CPU-Objekten werden von DirectML mit starken Referenzanzahlen verwaltet. Ihre Anwendung muss die Abhängigkeiten der CPU-Lebensdauer nicht manuell verwalten. Beispielsweise enthält jedes untergeordnete Gerät einen starken Verweis auf das übergeordnete Gerät.
- Lebensdauerabhängigkeiten zwischen GPU-Objekten oder Abhängigkeiten, die sich über CPU und GPU erstrecken, werden nicht automatisch verwaltet. Es liegt in der Verantwortung Ihrer Anwendung sicherzustellen, dass GPU-Ressourcen mindestens so lange bestehen bleiben, bis alle Aufgaben, die diese Ressourcen nutzen, auf der GPU abgeschlossen sind.
DirectML-Geräte
Das DirectML-Gerät ist ein threadsicheres zustandsloses Factoryobjekt. Jedes untergeordnete Gerät (siehe IDMLDeviceChild) enthält einen starken Verweis auf das übergeordnete DirectML-Gerät (siehe IDMLDevice). Das bedeutet, dass Sie die Schnittstelle des übergeordneten Geräts jederzeit von jeder Schnittstelle eines untergeordneten Geräts abrufen können.
Ein DirectML-Gerät enthält wiederum einen starken Verweis auf das Direct3D 12-Gerät, das zum Erstellen verwendet wurde (siehe ID3D12Device und abgeleitete Schnittstellen).
Da das DirectML-Gerät zustandslos ist, ist es implizit threadsicher. Sie können Methoden auf dem DirectML-Gerät von mehreren Threads gleichzeitig aufrufen, ohne dass eine externe Synchronisierung erforderlich ist.
Im Gegensatz zum Direct3D 12-Gerät ist das DirectML-Gerät jedoch kein Singletonobjekt. Sie können beliebig viele DirectML-Geräte erstellen. Sie können untergeordnete Geräte, die zu verschiedenen Geräten gehören, jedoch nicht kombinieren. Beispielsweise sind IDMLBindingTable und IDMLCompiledOperator zwei Arten von Gerätekindern (beide Schnittstellen werden direkt oder indirekt von IDMLDeviceChild abgeleitet). Sie dürfen keine Bindungstabelle (IDMLBindingTable) verwenden, um sie an einen Operator (IDMLCompiledOperator) zu binden, wenn der Operator und die Bindungstabelle zu verschiedenen DirectML-Geräteinstanzen gehören.
Da das DirectML-Gerät kein Singleton ist, tritt die Geräteentfernung pro Gerät auf, anstatt ein prozessweites Ereignis wie für ein Direct3D 12-Gerät zu sein. Weitere Informationen finden Sie unter Behandeln von Fehlern und Entfernen von Geräten in DirectML.
Lebensdaueranforderungen von GPU-Ressourcen
Wie Direct3D 12 synchronisiert DirectML nicht automatisch zwischen CPU und GPU. Außerdem bleiben Ressourcen nicht automatisch aktiv, während sie von der GPU verwendet werden. Stattdessen liegt diese Verantwortung bei Ihrer Anwendung.
Wenn Sie eine Befehlsliste ausführen, die DirectML-Dispatches enthält, muss Ihre Anwendung sicherstellen, dass GPU-Ressourcen verfügbar gehalten werden, bis alle Arbeiten mit diesen Ressourcen auf der GPU abgeschlossen sind.
Im Fall von IDMLCommandRecorder::RecordDispatch für einen DirectML-Operator, der die folgenden Objekte enthält.
- Die ausgeführte IDMLCompiledOperator-Schnittstelle (oder stattdessen IDMLOperatorInitializer, falls eine Operatorinitialisierung ausgeführt wird)
- Die IDMLCompiledOperator-Schnittstelle, die die Bindungstabelle unterstützt, die zum Binden des Operators verwendet wird
- Die ID3D12Resource-Objekte , die als Eingaben/Ausgaben des Operators gebunden sind.
- Die ID3D12Resource-Objekte, die als persistente und temporäre Ressourcen gebunden sind, sofern zutreffend.
- Die ID3D12CommandAllocator-Schnittstelle, die die Befehlsliste selbst unterstützt
Nicht alle DirectML-Schnittstellen stellen GPU-Ressourcen dar. Beispielsweise muss eine Bindungstabelle nicht aktiv bleiben, bis alle Verteiler, die sie verwenden, die Ausführung auf der GPU abgeschlossen haben. Das liegt daran, dass die Bindungstabelle selbst keine GPU-Ressourcen besitzt. Diese Ressourcen besitzt stattdessen der Deskriptorheap. Daher ist der zugrunde liegende Deskriptor heap das Objekt, das bis zur Ausführung aktiv gehalten werden muss, und nicht die Bindungstabelle selbst.
In Direct3D 12 ist ein ähnliches Konzept vorhanden. Ein Befehls-Allocator muss am Leben gehalten werden, bis alle Ausführungen, die ihn verwenden, auf der GPU abgeschlossen sind, weil dieser den GPU-Speicher besitzt. Eine Befehlsliste besitzt jedoch keinen GPU-Speicher, sodass sie daher zurückgesetzt oder freigegeben werden kann, sobald sie zur Ausführung übermittelt wurde.
In DirectML müssen kompilierte Operatoren (IDMLCompiledOperator) und Operatorinitialisierer (IDMLOperatorInitializer) beide eigene GPU-Ressourcen direkt erhalten, sodass sie lebendig bleiben müssen, bis alle Verteiler, die sie verwenden, die Ausführung auf der GPU abgeschlossen haben. Darüber hinaus müssen alle verwendeten Direct3D 12 Ressourcen (Befehls-Zuordner, Deskriptor-Heaps, Puffer, zum Beispiel) ebenfalls von Ihrer Anwendung aufrechterhalten werden.
Wenn Sie ein Objekt vorzeitig freigeben, während es noch von der GPU verwendet wird, ist das Ergebnis nicht definiertes Verhalten, das das Risiko hat, geräteentfernung oder andere Fehler zu verursachen.
CPU- und GPU-Synchronisierung
DirectML selbst reicht keine Arbeit zur Ausführung auf der GPU ein. Stattdessen zeichnet die IDMLCommandRecorder::RecordDispatch-Methode den Ablauf dieser Arbeit in eine Befehlsliste zur späteren Ausführung auf. Ihre Anwendung muss dann die Befehlsliste für die Ausführung schließen und übermitteln, indem ID3D12CommandQueue::ExecuteCommandLists aufgerufen wird, wie bei jeder Direct3D 12-Befehlsliste.
Da DirectML selbst keine Arbeit zur Ausführung auf der GPU übermittelt, werden auch keine Fences erstellt, und es wird keinerlei CPU-/GPU-Synchronisierung für Sie ausgeführt. Es liegt in der Verantwortung Ihrer Anwendung, die entsprechenden Direct3D 12-Grundtypen zu verwenden, um bei Bedarf auf die Ausführung der übermittelten Arbeit auf der GPU zu warten. Weitere Informationen finden Sie unter ID3D12Fence und ID3D12CommandQueue::Signal.