Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Podobnie jak w przypadku direct3D 12 aplikacja DirectML musi (aby uniknąć niezdefiniowanego zachowania) prawidłowo zarządzać okresami istnienia obiektów i synchronizacją między procesorem CPU a procesorem GPU. DirectML jest zgodny z identycznym modelem okresu istnienia zasobów w modelu Direct3D 12.
- Zależności żywotności między dwoma obiektami CPU są obsługiwane przez DirectML przy użyciu silnych liczników odniesień. Aplikacja nie musi ręcznie zarządzać zależnościami okresu istnienia procesora CPU. Na przykład każde urządzenie podrzędne przechowuje silne odwołanie do urządzenia nadrzędnego.
- Zależności okresu istnienia między obiektami procesora GPU — lub zależnościami obejmującymi procesor CPU i procesor GPU — nie są zarządzane automatycznie. To Twoja aplikacja jest odpowiedzialna za to, aby zasoby GPU były dostępne co najmniej do czasu zakończenia pracy korzystającej z tych zasobów na GPU.
Urządzenia DirectML
Urządzenie DirectML jest bezstanowym obiektem fabrycznym bezpiecznym dla wątków. Każde podrzędne urządzenie (zobacz IDMLDeviceChild) przechowuje silne odwołanie do nadrzędnego urządzenia DirectML (zobacz IDMLDevice). Oznacza to, że zawsze można pobrać interfejs urządzenia nadrzędnego z dowolnego interfejsu podrzędnego urządzenia.
Urządzenie DirectML z kolei zawiera silne odwołanie do urządzenia Direct3D 12, które zostało użyte do jego utworzenia (zobacz ID3D12Device i pochodne interfejsy).
Ponieważ urządzenie DirectML jest bezstanowe, jest domyślnie bezpieczne wątkowo. Metody można wywołać na urządzeniu DirectML z wielu wątków jednocześnie bez konieczności synchronizacji zewnętrznej.
Jednak w przeciwieństwie do urządzenia Direct3D 12 urządzenie DirectML nie jest pojedynczym obiektem. Możesz utworzyć dowolną liczbę urządzeń DirectML. Nie można jednak mieszać elementów podrzędnych pochodzących z różnych urządzeń. Na przykład idMLBindingTable i IDMLCompiledOperator to dwa rodzaje elementów podrzędnych urządzeń (oba interfejsy pochodzą bezpośrednio lub pośrednio z identyfikatora IDMLDeviceChild). Nie można też użyć tabeli powiązań (IDMLBindingTable) do powiązania dla operatora (IDMLCompiledOperator), jeśli operator i tabela powiązań należą do różnych wystąpień urządzeń DirectML.
Ponieważ urządzenie DirectML nie jest pojedynczym urządzeniem, usuwanie urządzenia odbywa się na poszczególnych urządzeniach, zamiast być zdarzeniem obejmującym cały proces, tak jak w przypadku urządzenia Direct3D 12. Aby uzyskać więcej informacji, zobacz Obsługa błędów i usuwania urządzeń w języku DirectML.
Wymagania dotyczące okresu istnienia zasobów procesora GPU
Podobnie jak direct3D 12, directML nie synchronizuje się automatycznie między procesorem CPU i procesorem GPU; ani nie automatycznie utrzymuje zasobów przy życiu, gdy są one używane przez procesor GPU. Zamiast tego są to obowiązki twojej aplikacji.
Podczas wykonywania listy poleceń zawierającej polecenia DirectML, aplikacja musi upewnić się, że zasoby GPU pozostają aktywne, dopóki nie zostanie zakończone wykonywanie wszystkich operacji na GPU korzystających z tych zasobów.
W przypadku IDMLCommandRecorder::RecordDispatch dla operatora DirectML, obejmującego następujące obiekty.
- Wykonywany jest IDMLCompiledOperator (lub IDMLOperatorInitializer, jeśli wykonywana jest inicjalizacja operatora).
- IdMLCompiledOperator obsługuje tabelę powiązań używaną do wiązania operatora.
- Obiekty ID3D12Resource powiązane jako dane wejściowe/wyjściowe operatora.
- Obiekty ID3D12Resource powiązane jako trwałe i tymczasowe zasoby, jeśli ma to zastosowanie.
- ID3D12CommandAllocator obsługujący samą listę poleceń.
Nie wszystkie interfejsy DirectML reprezentują zasoby procesora GPU. Na przykład tabela wiązania nie musi być zachowywana aż do ukończenia wszystkich operacji wykonywanych przy użyciu procesora GPU. Dzieje się tak, ponieważ sama tabela powiązań nie jest właścicielem żadnych zasobów GPU. Zamiast tego zajmuje się tym sterta deskryptora. W związku z tym bazowa sterta deskryptora jest obiektem, który musi być utrzymywany do momentu zakończenia wykonywania się, a nie samej tabeli powiązań.
Podobna koncepcja istnieje w wersji Direct3D 12. Alokator poleceń musi być utrzymywany przy życiu do momentu ukończenia wszystkich wykonań przy użyciu procesora GPU; ponieważ jest właścicielem pamięci procesora GPU. Jednak lista poleceń nie jest właścicielem pamięci procesora GPU, dlatego można ją zresetować lub zwolnić zaraz po przesłaniu do wykonania.
W języku DirectML skompilowane operatory (IDMLCompiledOperator) i inicjatory operatorów (IDMLOperatorInitializer) są bezpośrednio właścicielami zasobów procesora GPU, więc muszą być przechowywane przy życiu, dopóki wszystkie wysyłki przy użyciu nich nie zostały wykonane na procesorze GPU. Pamiętaj również, że wszystkie używane zasoby Direct3D 12 (alokatory poleceń, sterty deskryptorów, bufory, jako przykłady) powinny być utrzymywane przy życiu przez aplikację.
Jeśli przedwcześnie zwolnisz obiekt, gdy jest on nadal używany przez procesor graficzny, wynik to niezdefiniowane zachowanie, co może spowodować usunięcie urządzenia lub inne błędy.
Synchronizacja procesora CPU i procesora GPU
DirectML nie przesyła żadnych zadań do wykonania na GPU. Zamiast tego metoda IDMLCommandRecorder::RecordDispatchrejestruje wysyłanie tej pracy do listy poleceń w celu późniejszego wykonania. Twoja aplikacja musi następnie zamknąć i przesłać listę poleceń do wykonania, wywołując metodę ID3D12CommandQueue::ExecuteCommandLists, tak jak w przypadku dowolnej listy poleceń Direct3D 12.
Ponieważ DirectML sam nie przesyła żadnej pracy do wykonania na GPU, nie tworzy również żadnych barier ani nie wykonuje żadnej formy synchronizacji CPU/GPU w Twoim imieniu. Obowiązkiem aplikacji jest użycie odpowiednich elementów pierwotnych Direct3D 12 do oczekiwania na przesłane prace w celu ukończenia wykonywania na procesorze GPU, jeśli to konieczne. Aby uzyskać więcej informacji, zobacz ID3D12Fence i ID3D12CommandQueue::Signal.