Temporização (Gráficos do Direct3D 12)

Esta secção cobre a consulta de carimbos temporais e a calibração dos contadores de carimbo de tempo da GPU e da CPU.

Tip

Para perfil interativo da GPU e análise de temporização de frames, use o PIX para o Windows. O PIX fornece captura de GPU, captura de tempos e vistas de monitorização do sistema que correlacionam visualmente a atividade da CPU e da GPU, o que faz dele o ponto de partida recomendado antes de escrever infraestrutura personalizada para consultas de carimbo temporal. O SDK Agility do DirectX 12 garante que tem as funcionalidades de execução mais recentes disponíveis para perfil e diagnóstico, independentemente da versão do sistema operativo.

Frequência da marca temporal

A sua aplicação pode consultar a frequência da marca temporal da GPU para cada fila de comandos (consulte o método ID3D12CommandQueue::GetTimestampFrequency).

A frequência devolvida é medida em Hz (tiques/seg). Se a fila de comandos especificada não suportar marcas temporais (ver a tabela na secção Consultas), esta API falha (e devolve E_FAIL). D3D12_COMMAND_LIST_TYPE_DIRECT e D3D12_COMMAND_LIST_TYPE_COMPUTE suportam sempre marcas temporais. D3D12_COMMAND_LIST_TYPE_COPY suporta opcionalmente marcas temporais se o membro D3D12_FEATURE_DATA_D3D12_OPTIONS3::CopyQueueTimestampQueriesSupported for TRUE.

Calibração da marca temporal

O D3D12 permite que as aplicações correlacionem resultados obtidos de consultas de carimbo temporal com resultados obtidos ao chamar QueryPerformanceCounter. Isto é ativado pela chamada ID3D12CommandQueue::GetClockCalibration.

Uma marca temporal é registada pela GPU quando a GPU termina toda a carga de trabalho anterior. É o mesmo comportamento adotado pelo Direct3D 11 (ver D3D11_QUERY_TIMESTAMP na Especificação Funcional do Direct3D 11.3 sobre GitHub). Isto significa que as consultas de marca temporal são uma operação bottom-of-pipe (BOP) no Direct3D 12.

GetClockCalibration obtém uma amostra do contador de marcas temporais da GPU para uma determinada fila de comandos e obtém uma amostra do contador da CPU através de QueryPerformanceCounter praticamente ao mesmo tempo. Mais uma vez, esta API falha (devolvendo E_FAIL) se a fila de comandos especificada não suportar marcas temporais (ver a tabela no tópico Consultas).

Note que os contadores de carimbo temporal da GPU e CPU não estão necessariamente diretamente relacionados com a velocidade de relógio destes processadores, mas funcionam a partir dos ticks de carimbo temporal.

Warning

Os relógios de marca temporal da GPU podem deixar de avançar em alguns tipos de hardware quando a GPU está inativa, pelo que a correlação pode sofrer desvio. Para evitar isto, chame ID3D12Device::SetStablePowerState durante o desenvolvimento (requer o Modo Desenvolvedor ativado).

Consultas de data/hora

Pode obter marcas temporais no âmbito de uma lista de comandos (em vez de uma chamada efetuada pela CPU numa fila de comandos) através de consultas de marca temporal. (Consulte Consultas para mais informações sobre consultas em geral).

Todas as consultas de marca temporal utilizam o tipo D3D12_QUERY_TYPE_TIMESTAMP para a consulta propriamente dita. No entanto, devido a limitações de hardware, D3D12_COMMAND_LIST_TYPE_DIRECT e D3D12_COMMAND_LIST_TYPE_COMPUTE usam um D3D12_QUERY_HEAP_TYPE diferente daquele que D3D12_COMMAND_LIST_TYPE_COPY utiliza.

As filas diretas e de computação utilizam D3D12_QUERY_HEAP_TYPE_TIMESTAMP.

As filas de cópia usam D3D12_QUERY_HEAP_TYPE_COPY_QUEUE_TIMESTAMP.

As consultas de fila de cópia são suportadas apenas se o membro D3D12_FEATURE_DATA_D3D12_OPTIONS3::CopyQueueTimestampQueriesSupported for TRUE.

As consultas de marca temporal, uma vez resolvidas através de ID3D12GraphicsCommandList::ResolveQueryData, produzem um valor UINT64 que representa ticks, tal como o devolvido por ID3D12CommandQueue::GetClockCalibration, e, como tal, tem de ser dividido pela frequência da fila para obter a duração em segundos.

Importante

Para maior precisão, utilize aritmética de vírgula flutuante ao calcular intervalos em segundos ou milissegundos de marcas temporais. Por exemplo, use queriedTicks / (double)Frequency em vez de queriedTicks / Frequency.

Contadores e Consultas

ID3D12Device::SetStablePowerState

ID3D12Object::SetName

ID3DUserDefinedAnnotation

Medição de Desempenho