Monitorização do contexto
Este artigo fornece informações sobre monitoramento de contexto, que foi introduzido no Windows 10 (WDDM 2.0).
O monitoramento de contexto permite uma sincronização flexível entre mecanismos de GPU ou entre núcleos de CPU e mecanismos de GPU. Um objeto de cerca monitorado é uma forma avançada de sincronização de cerca que permite que um núcleo de CPU ou um mecanismo de GPU sinalize ou aguarde em um objeto de cerca específico.
Criação de cercas monitoradas
O runtime do Direct3D cria um objeto de barreira monitorada chamando a função de retorno do driver em modo de usuário (UMD) pfnCreateSynchronizationObject2Cb com a estrutura D3DDDICB_CREATESYNCHRONIZATIONOBJECT2. O membro Info dessa estrutura é uma estrutura D3DDDI_SYNCHRONIZATIONOBJECTINFO2 que descreve o objeto de sincronização a ser criado. O runtime define Info.Type como D3DDDI_MONITORED_FENCE para indicar que a estrutura Info.MonitoredFence deve ser usada durante a criação.
O objeto de cerca monitorado criado tem os seguintes atributos:
- Um valor de cerca inicial.
- Bandeiras que especificam o seu comportamento de espera e sinalização.
Após a criação, um objeto de cerca monitorado é retornado com as seguintes informações:
Número | Descrição |
---|---|
hSyncObject | Manipule o objeto de sincronização. Esse identificador é usado em chamadas subsequentes para Dxgkrnl. |
FenceValueCPUVirtualAddress | Mapeamento somente leitura do valor de barreira (64 bits) para a CPU. Este endereço é mapeado como WB (cacheável) do ponto de vista da CPU em plataformas que suportam coerência de E/S, e como UC (não cacheável) em outras plataformas. Permite que a CPU acompanhe o progresso da cerca apenas lendo este local de memória. A CPU não tem permissão para gravar neste local de memória. Para sinalizar a cerca, é necessário que a CPU chame o SignalSynchronizationObjectFromCpuCb. Os adaptadores que suportam IoMmu devem usar esse endereço para acesso à GPU. Neste caso, o endereço é mapeado como leitura-gravação. |
FenceValueGPUVirtualAddress | Mapeamento de leitura/escrita do valor de "fence" (64 bits) para a GPU. Esse endereço é mapeado como exigindo coerência de E/S em plataformas que o suportam. Para sinalizar a barreira, a GPU tem permissão para gravar diretamente neste endereço virtual da GPU. As GPUs IoMmu não devem usar esse endereço. |
O valor de delimitador é um valor de 64 bits com os seus respetivos endereços virtuais alinhados em uma fronteira de 64 bits. As GPUs devem declarar se são capazes de atualizar valores de 64 bits atomicamente, conforme visíveis pela CPU, através do indicador adicionado DXGK_VIDSCHCAPS::flag No64BitAtomics. Se uma GPU for capaz de atualizar apenas valores de 32 bits atomicamente, o sistema operativo lida automaticamente com o caso de contorno de barreira. No entanto, ele coloca uma restrição de que os valores pendentes de cerca de espera e sinal não podem estar a mais de UINT_MAX/2 de distância do último valor de cerca sinalizado.
Sinal GPU
Se um motor de GPU não for capaz de escrever numa cerca monitorizada utilizando o seu endereço virtual, o UMD usa o retorno de chamada SignalSynchronizationObjectFromGpuCb para enfileirar um pacote de sinal de software para o contexto da GPU.
Para sinalizar a cerca da GPU, o UMD insere um comando fence write em um fluxo de comando de contexto diretamente sem passar pelo modo kernel. O mecanismo pelo qual o kernel monitora o progresso da cerca varia dependendo se um mecanismo de GPU específico suporta a implementação básica ou avançada da cerca monitorada.
Quando um buffer de comandos concluir a execução na GPU, Dxgkrnl:
- Passa pela lista de objetos de vedação com aguardas pendentes que poderiam ser sinalizadas para este processo.
- Lê o valor atual da cerca.
- Determina se há alguma espera que precisa ser removida.
Espera da GPU
Para aguardar numa cerca monitorada num motor de GPU, o UMD primeiro precisa descarregar o seu buffer de comandos pendente e, em seguida, chamar WaitForSynchronizationObjectFromGpuCb especificar o objeto de cerca (hSyncObject) e o valor da cerca que está a ser aguardado. Dxgkrnl enfileira a dependência para o seu banco de dados interno e, em seguida, retorna imediatamente para o UMD para que possa continuar a enfileirar o trabalho atrás da operação de espera. Os buffers de comando enviados após a operação de espera não são agendados para execução até que a operação de espera seja satisfeita.
Sinal da CPU
O callback SignalSynchronizationObjectFromCpuCb foi adicionado para permitir que a CPU sinalize um objeto de barreira monitorada. Quando a CPU sinaliza um objeto de cerca monitorado, Dxgkrnl atualiza o local da memória da cerca com o valor sinalizado. Esse valor torna-se imediatamente visível para qualquer leitor em modo utilizador e liberta imediatamente qualquer espera satisfeita.
Espera da CPU
Foi adicionado um callback WaitForSynchronizationObjectFromCpuCb para permitir que a CPU aguarde em um objeto de sincronização monitorado. Estão disponíveis duas formas de operações de espera:
- No primeiro formulário, WaitForSynchronizationObjectFromCpuCb bloqueia até que a espera termine.
- No segundo método, WaitForSynchronizationObjectFromCpuCb recebe um identificador para um evento de CPU que é sinalizado quando a condição de espera for satisfeita.