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.
Requisitos de barreira de UAV (Exibição de Acesso Não Ordenado)
Barreiras UAV no Direct3D 12
No Direct3D 12, as expedições de sombreador de computação adjacentes dentro da mesma lista de comandos têm permissão para serem executadas em paralelo na GPU, a menos que estejam sincronizadas com uma barreira UAV (exibição de acesso não ordenado) intermediária. Isso pode melhorar o desempenho aumentando a utilização do hardware da GPU. No entanto, por padrão, sem o uso de uma barreira UAV, a execução paralela de dois despachos adjacentes pode causar uma condição de corrida se existir uma dependência de dados entre os dois despachos; ou se ambos os despachos executarem gravações UAV nas mesmas regiões da memória.
Uma barreira UAV força todos os despachos enviados anteriormente a concluir a execução na GPU antes que os despachos subsequentes possam começar. As barreiras UAV são usadas para sincronizar entre despachos na mesma lista de comandos para evitar corridas de dados. Você pode emitir uma barreira UAV usando o método ID3D12GraphicsCommandList::ResourceBarrier .
Barreiras UAV no DirectML
No DirectML, os operadores são expedidos de maneira semelhante à maneira como os sombreadores de computação são expedidos no Direct3D 12. Ou seja, despachos adjacentes de operadores têm permissão para executar em paralelo na GPU, a menos que exista uma barreira UAV intermediária entre eles. Um modelo típico de aprendizado de máquina contém dependências de dados entre seus operadores; Por exemplo, a saída de um operador alimenta a entrada de outro. Portanto, é importante usar barreiras UAV para sincronizar corretamente os despachos.
O DirectML garante que ele só lerá (e nunca gravará) tensores de entrada. Ele também garante que nunca fabricará gravações em um tensor de saída fora do intervalo do membro DML_BUFFER_TENSOR_DESC::TotalTensorSizeInBytes do tensor. Isso significa que as dependências de dados entre operadores no DirectML podem ser raciocinadas examinando apenas as associações de entrada e saída de um operador.
Por exemplo, essas garantias permitem que você despache dois operadores que vinculam a mesma região de um recurso como uma entrada, sem precisar emitir uma barreira UAV intermediária. Isso é sempre seguro porque o DirectML nunca grava em tensores de entrada. Como outro exemplo, é sempre seguro associar os tensores de saída de duas expedições de operador simultâneas ao mesmo recurso do Direct3D 12 (desde que seus tensores não se sobreponham), pois o DirectML nunca grava fora dos limites de um tensor (conforme definido pelo DML_BUFFER_TENSOR_DESC::TotalTensorSizeInBytes do tensor).
Como as barreiras de UAV são uma forma de sincronização, o uso desnecessário de barreiras de UAV pode afetar negativamente o desempenho. Portanto, é melhor usar o número mínimo de barreiras UAV necessárias para sincronizar corretamente os despachos em uma lista de comandos.
Exemplo 1
No exemplo a seguir, a saída de um operador de convolução é alimentada em uma ativação de ReLU, seguida por uma normalização em lote.
CONVOLUTION (conv1)
|
ACTIVATION_RELU (relu1)
|
BATCH_NORMALIZATION (batch1)
Como existe uma dependência de dados entre os três operadores, você precisará de uma barreira UAV entre cada expedição sucessiva (consulte IDMLCommandRecorder::RecordDispatch).
-
dmlCommandRecorder->RecordDispatch(d3d12CommandList,
conv1)
-
d3d12CommandList->ResourceBarrier(
Barreira para drone)
-
dmlCommandRecorder->RecordDispatch(d3d12CommandList,
relu1)
-
d3d12CommandList->ResourceBarrier(
Barreira para drone)
-
dmlCommandRecorder->RecordDispatch(d3d12CommandList,
lote 1)
Exemplo 2
MAX_POOLING (pool1)
/ \
CONVOLUTION CONVOLUTION
(conv1) (conv2)
\ /
JOIN (join1)
Aqui, a saída do pooling é alimentada em duas convoluções, cujas saídas são então concatenadas usando o operador JOIN. Existe uma dependência de dados entre pool1
e ambos conv1
e conv2
; bem como entre ambos conv1
e conv2
e .join1
Aqui está uma maneira válida de executar este gráfico.
-
dmlCommandRecorder->RecordDispatch(d3d12CommandList,
piscina1)
-
d3d12CommandList->ResourceBarrier(
Barreira para drone)
-
dmlCommandRecorder->RecordDispatch(d3d12CommandList,
conv1)
-
dmlCommandRecorder->RecordDispatch(d3d12CommandList,
conv2)
-
d3d12CommandList->ResourceBarrier(
Barreira para drone)
-
dmlCommandRecorder->RecordDispatch(d3d12CommandList,
juntar1)
Nesse caso, conv1
e conv2
são capazes de executar simultaneamente na GPU, o que pode melhorar o desempenho.
Requisitos do estado de barreira de recursos
Como chamador, é sua responsabilidade garantir que todos os recursos do Direct3D 12 estejam no estado correto de barreira de recursos antes de executar expedições do DirectML na GPU. O DirectML não executa nenhuma barreira de transição em seu nome.
Antes da execução de IDMLCommandRecorder::RecordDispatch na GPU, você deve fazer a transição de todos os recursos associados para o estado D3D12_RESOURCE_STATE_UNORDERED_ACCESS ou para um estado implicitamente promovível para D3D12_RESOURCE_STATE_UNORDERED_ACCESS, como D3D12_RESOURCE_STATE_COMMON. Após a conclusão dessa chamada, os recursos permanecerão no estado D3D12_RESOURCE_STATE_UNORDERED_ACCESS. Para obter mais detalhes, consulte Associação no DirectML.