Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Assim como no Direct3D 12, seu aplicativo DirectML deve (para evitar comportamento indefinido) gerenciar corretamente os tempos de vida do objeto e a sincronização entre a CPU e a GPU. O DirectML segue um modelo de tempo de vida de recurso idêntico ao do Direct3D 12.
- As dependências de tempo de vida entre dois objetos de CPU são mantidas pelo DirectML usando contagens de referência fortes. Seu aplicativo não precisa gerenciar manualmente as dependências do tempo de vida da CPU. Por exemplo, cada filho de dispositivo tem uma forte referência ao seu dispositivo pai.
- As dependências de tempo de vida entre objetos de GPU, ou dependências que abrangem CPU e GPU, não são gerenciadas automaticamente. É responsabilidade do aplicativo garantir que os recursos da GPU permaneçam pelo menos até que todo o trabalho que usa esse recurso tenha concluído a execução na GPU.
Dispositivos DirectML
O dispositivo DirectML é um objeto de fábrica sem estado thread-safe. Cada filho de dispositivo (consulte IDMLDeviceChild) contém uma forte referência ao seu dispositivo DirectML pai (consulte IDMLDevice). Isso significa que você sempre pode recuperar a interface do dispositivo pai de qualquer interface filho do dispositivo.
Um dispositivo DirectML, por sua vez, contém uma forte referência ao dispositivo Direct3D 12 que foi usado para criá-lo (consulte ID3D12Device e interfaces derivadas).
Como o dispositivo DirectML não tem estado, ele é implicitamente thread-safe. Você pode chamar métodos no dispositivo DirectML de vários threads simultaneamente sem a necessidade de sincronização externa.
No entanto, ao contrário do dispositivo Direct3D 12, o dispositivo DirectML não é um objeto singleton. Você é livre para criar quantos dispositivos DirectML desejar. No entanto, você não pode misturar e combinar filhos de dispositivos que pertençam a dispositivos diferentes. Por exemplo, IDMLBindingTable e IDMLCompiledOperator são dois tipos de filhos de dispositivo (ambas as interfaces derivam direta ou indiretamente de IDMLDeviceChild). E você não poderá usar uma tabela de associação (IDMLBindingTable) para associar um operador (IDMLCompiledOperator) se o operador e a tabela de associação pertencerem a instâncias de dispositivo DirectML diferentes.
Como o dispositivo DirectML não é um singleton, a remoção do dispositivo ocorre por dispositivo, em vez de ser um evento em todo o processo, como é para um dispositivo Direct3D 12. Para obter mais informações, consulte Manipulando erros e remoção de dispositivo no DirectML.
Requisitos de tempo de vida dos recursos de GPU
Assim como o Direct3D 12, o DirectML não sincroniza automaticamente entre a CPU e a GPU; nem mantém automaticamente os recursos ativos enquanto eles estão em uso pela GPU. Em vez disso, essas são responsabilidades de sua inscrição.
Ao executar uma lista de comandos que contém expedições do DirectML, seu aplicativo deve garantir que os recursos da GPU sejam mantidos ativos até que todo o trabalho que usa esses recursos tenha concluído a execução na GPU.
No caso de IDMLCommandRecorder::RecordDispatch para um operador DirectML, isso inclui os objetos a seguir.
- O IDMLCompiledOperator que está sendo executado (ou IDMLOperatorInitializer em vez disso, se estiver executando a inicialização do operador).
- O IDMLCompiledOperator que dá suporte à tabela de associação que está sendo usada para associar o operador.
- Os objetos ID3D12Resource associados como entradas/saídas do operador.
- Os objetos ID3D12Resource associados como recursos persistentes e temporários, se aplicável.
- O ID3D12CommandAllocator que dá suporte à própria lista de comandos.
Nem todas as interfaces DirectML representam recursos de GPU. Por exemplo, uma tabela de associação não precisa ser mantida ativa até que todos os despachos que a usam tenham concluído a execução na GPU. Isso ocorre porque a tabela de associação em si não possui nenhum recurso de GPU. Em vez disso, o heap do descritor faz. Portanto, o heap do descritor subjacente é o objeto que deve ser mantido ativo até que a execução seja concluída, e não a tabela de associação em si.
Um conceito semelhante existe no Direct3D 12. Um alocador de comandos deve ser mantido ativo até que todas as execuções que o usam tenham sido concluídas na GPU; já que possui memória GPU. No entanto, uma lista de comandos não possui memória de GPU, portanto, ela pode ser redefinida ou liberada assim que for enviada para execução.
No DirectML, os operadores compilados (IDMLCompiledOperator) e os inicializadores de operador (IDMLOperatorInitializer) possuem recursos de GPU diretamente, portanto, devem ser mantidos ativos até que todas as expedições que os usam tenham concluído a execução na GPU. Além disso, qualquer recurso do Direct3D 12 que esteja sendo usado (alocadores de comando, heaps de descritor, buffers, como exemplos) deve ser mantido ativo da mesma forma pelo aplicativo.
Se você liberar prematuramente um objeto enquanto ele ainda estiver em uso pela GPU, o resultado será um comportamento indefinido, que tem o potencial de causar a remoção do dispositivo ou outros erros.
Sincronização de CPU e GPU
O DirectML não envia nenhum trabalho para execução na GPU. Em vez disso, o método IDMLCommandRecorder::RecordDispatchregistra a expedição desse trabalho em uma lista de comandos para execução posterior. Seu aplicativo deve fechar e enviar sua lista de comandos para execução chamando ID3D12CommandQueue::ExecuteCommandLists, como acontece com qualquer lista de comandos do Direct3D 12.
Como o DirectML não envia nenhum trabalho para execução na GPU, ele também não cria cercas, nem executa nenhuma forma de sincronização de CPU/GPU em seu nome. É responsabilidade do seu aplicativo usar os primitivos apropriados do Direct3D 12 para aguardar que o trabalho enviado conclua a execução na GPU, se necessário. Para obter mais informações, consulte ID3D12Fence e ID3D12CommandQueue::Signal.