Aquisição de carimbos de data/hora de alta resolução

O Windows fornece APIs que você pode usar para adquirir carimbos de data/hora de alta resolução ou medir intervalos de tempo. A API primária para código nativo é QueryPerformanceCounter (QPC). Para drivers de dispositivo, a API do modo kernel é KeQueryPerformanceCounter. Para código gerenciado, a classe System.Diagnostics.Stopwatch usa QPC como sua base de tempo precisa.

O QPC é independente de e não está sincronizado com nenhuma referência de tempo externo. Para recuperar carimbos de data/hora que podem ser sincronizados com uma referência de hora externa, como UTC (Tempo Universal Coordenado) para uso em medidas de tempo do dia de alta resolução, use GetSystemTimePreciseAsFileTime.

Carimbos de data/hora e medidas de intervalo de tempo são parte integrante das medidas de desempenho do computador e da rede. Essas operações de medição de desempenho incluem a computação do tempo de resposta, da taxa de transferência e da latência, bem como a execução do código de criação de perfil. Cada uma dessas operações envolve uma medição de atividades que ocorrem durante um intervalo de tempo definido por um evento inicial e final que pode ser independente de qualquer referência externa de hora do dia.

O QPC normalmente é o melhor método a ser usado para eventos de carimbo de data/hora e medir pequenos intervalos de tempo que ocorrem no mesmo sistema ou máquina virtual. Considere usar GetSystemTimePreciseAsFileTime quando quiser carimbar eventos em vários computadores, desde que cada computador esteja participando de um esquema de sincronização de tempo, como o Protocolo de Tempo de Rede (NTP). O QPC ajuda você a evitar dificuldades que podem ser encontradas com outras abordagens de medição de tempo, como ler o TSC (contador de carimbo de data/hora) do processador diretamente.

Suporte a QPC em versões do Windows

O QPC foi introduzido no Windows 2000 e no Windows XP e evoluiu para aproveitar as melhorias na plataforma de hardware e nos processadores. Aqui, descrevemos as características do QPC em diferentes versões do Windows para ajudá-lo a manter o software executado nessas versões do Windows.

Windows XP e Windows 2000

O QPC está disponível no Windows XP e no Windows 2000 e funciona bem na maioria dos sistemas. No entanto, o BIOS de alguns sistemas de hardware não indicou as características da CPU de hardware corretamente (um TSC não invariável) e alguns sistemas multiprocessadores ou multiprocessadores usaram processadores com TSCs que não puderam ser sincronizados entre núcleos. Sistemas com firmware falho que executam essas versões do Windows podem não fornecer a mesma leitura de QPC em núcleos diferentes se usarem o TSC como base para QPC.

Windows Vista e Windows Server 2008

Todos os computadores fornecidos com o Windows Vista e o Windows Server 2008 usaram um contador de plataforma (HPET (Temporizador de Eventos de Alta Precisão)) ou o Temporizador de Gerenciamento de Energia acPI (temporizador PM) como base para QPC. Esses temporizadores de plataforma têm latência de acesso maior do que o TSC e são compartilhados entre vários processadores. Isso limita a escalabilidade do QPC se ele for chamado simultaneamente de vários processadores.

Windows 7 e Windows Server 2008 R2

A maioria dos computadores Windows 7 e Windows Server 2008 R2 tem processadores com TSCs de taxa constante e usam esses contadores como base para QPC. Os TSCs são contadores de hardware por processador de alta resolução que podem ser acessados com latência e sobrecarga muito baixas (na ordem de 10s ou 100s de ciclos de computador, dependendo do tipo de processador). O Windows 7 e o Windows Server 2008 R2 usam TSCs como base do QPC em sistemas de domínio de relógio único em que o sistema operacional (ou o hipervisor) é capaz de sincronizar rigidamente os TSCs individuais em todos os processadores durante a inicialização do sistema. Nesses sistemas, o custo de leitura do contador de desempenho é significativamente menor em comparação com os sistemas que usam um contador de plataforma. Além disso, não há sobrecarga adicional para chamadas simultâneas e consultas de modo de usuário geralmente ignoram chamadas do sistema, o que reduz ainda mais a sobrecarga. Em sistemas em que o TSC não é adequado para manutenção de tempo, o Windows seleciona automaticamente um contador de plataforma (o temporizador HPET ou o temporizador do ACPI PM) como base para QPC.

Windows 8, Windows 8.1, Windows Server 2012 e Windows Server 2012 R2

Windows 8, Windows 8.1, Windows Server 2012 e Windows Server 2012 R2 usam TSCs como base para o contador de desempenho. O algoritmo de sincronização TSC foi significativamente aprimorado para acomodar melhor sistemas grandes com muitos processadores. Além disso, o suporte para a nova API precisa de hora do dia foi adicionado, o que permite a aquisição de carimbos de data/hora precisos do relógio de parede do sistema operacional. Para obter mais informações, consulte GetSystemTimePreciseAsFileTime. Em dispositivos Windows RT e Windows 11 e Windows 10 usando processadores Arm, o contador de desempenho é baseado em um contador de plataforma proprietário ou no contador do sistema fornecido pelo Temporizador Genérico arm se a plataforma estiver tão equipada.

Diretrizes para adquirir carimbos de data/hora

O Windows tem e continuará investindo no fornecimento de um contador de desempenho confiável e eficiente. Quando você precisar de carimbos de data/hora com uma resolução de 1 microssegundo ou melhor e não precisar que os carimbos de data/hora sejam sincronizados com uma referência de hora externa, escolha QueryPerformanceCounter, KeQueryPerformanceCounter ou KeQueryInterruptTimePrecise. Quando precisar de carimbos de data/hora sincronizados em UTC com uma resolução de 1 microssegundo ou melhor, escolha GetSystemTimePreciseAsFileTime ou KeQuerySystemTimePrecise.

Em um número relativamente pequeno de plataformas que não podem usar o registro TSC como base QPC , por exemplo, por motivos explicados em Informações do temporizador de hardware, adquirir carimbos de data/hora de alta resolução pode ser significativamente mais caro do que adquirir carimbos de data/hora com resolução mais baixa. Se a resolução de 10 a 16 milissegundos for suficiente, você poderá usar GetTickCount64, QueryInterruptTime, QueryUnbiasedInterruptTime, KeQueryInterruptTime ou KeQueryUnbiasedInterruptTime para obter carimbos de data/hora que não são sincronizados com uma referência de hora externa. Para carimbos de data/hora sincronizados em UTC, use GetSystemTimeAsFileTime ou KeQuerySystemTime. Se for necessária uma resolução mais alta, você poderá usar QueryInterruptTimePrecise, QueryUnbiasedInterruptTimePrecise ou KeQueryInterruptTimePrecise para obter carimbos de data/hora.

Em geral, os resultados do contador de desempenho são consistentes em todos os processadores em sistemas de vários núcleos e multiprocessador, mesmo quando medidos em threads ou processos diferentes. Aqui estão algumas exceções a esta regra:

  • Sistemas operacionais pré-Windows Vista executados em determinados processadores podem violar essa consistência devido a um destes motivos:

    • Os processadores de hardware têm um TSC não invariável e o BIOS não indica essa condição corretamente.
    • O algoritmo de sincronização TSC usado não era adequado para sistemas com um grande número de processadores.
  • Ao comparar os resultados do contador de desempenho adquiridos de threads diferentes, considere valores que diferem ± 1 tique para ter uma ordenação ambígua. Se os carimbos de data/hora forem retirados do mesmo thread, essa ± incerteza de 1 escala não se aplicará. Nesse contexto, o termo tique refere-se a um período de tempo igual a 1 ÷ (a frequência do contador de desempenho obtido de QueryPerformanceFrequency).

Quando você usa o contador de desempenho em sistemas de servidores grandes com domínios de vários relógios que não são sincronizados em hardware, o Windows determina que o TSC não pode ser usado para fins de tempo e seleciona um contador de plataforma como base para QPC. Embora esse cenário ainda produz carimbos de data/hora confiáveis, a latência de acesso e a escalabilidade são afetadas negativamente. Portanto, conforme mencionado anteriormente nas diretrizes de uso anteriores, use apenas as APIs que fornecem 1 microssegundo ou melhor resolução quando essa resolução for necessária. O TSC é usado como base para QPC em sistemas de domínio de vários relógios que incluem a sincronização de hardware de todos os domínios de relógio do processador, pois isso efetivamente faz com que eles funcionem como um sistema de domínio de relógio único.

A frequência do contador de desempenho é corrigida na inicialização do sistema e é consistente em todos os processadores, portanto, você só precisa consultar a frequência de QueryPerformanceFrequency à medida que o aplicativo é inicializado e, em seguida, armazenar em cache o resultado.

Virtualização

Espera-se que o contador de desempenho funcione de forma confiável em todas as máquinas virtuais convidadas em execução em hipervisores implementados corretamente. No entanto, os hipervisores que estão em conformidade com a interface do hipervisor versão 1.0 e exibem a iluminação do tempo de referência podem oferecer uma sobrecarga substancialmente menor. Para obter mais informações sobre interfaces e esclarecimentos de hipervisor, consulte Especificações do hipervisor.

Uso direto do TSC

Desencorajamos fortemente o uso da instrução do processador RDTSC ou RDTSCP para consultar diretamente o TSC porque você não obterá resultados confiáveis em algumas versões do Windows, em migrações dinâmicas de máquinas virtuais e em sistemas de hardware sem TSCs invariáveis ou totalmente sincronizados. Em vez disso, incentivamos você a usar qpc para aproveitar a abstração, consistência e portabilidade que ele oferece.

Exemplos de aquisição de carimbos de data/hora

Os vários exemplos de código nestas seções mostram como adquirir carimbos de data/hora.

Usando QPC em código nativo

Este exemplo mostra como usar qpc em código nativo C e C++.

LARGE_INTEGER StartingTime, EndingTime, ElapsedMicroseconds;
LARGE_INTEGER Frequency;

QueryPerformanceFrequency(&Frequency); 
QueryPerformanceCounter(&StartingTime);

// Activity to be timed

QueryPerformanceCounter(&EndingTime);
ElapsedMicroseconds.QuadPart = EndingTime.QuadPart - StartingTime.QuadPart;


//
// We now have the elapsed number of ticks, along with the
// number of ticks-per-second. We use these values
// to convert to the number of elapsed microseconds.
// To guard against loss-of-precision, we convert
// to microseconds *before* dividing by ticks-per-second.
//

ElapsedMicroseconds.QuadPart *= 1000000;
ElapsedMicroseconds.QuadPart /= Frequency.QuadPart;

Adquirir carimbos de data/hora de alta resolução do código gerenciado

Este exemplo mostra como usar a classe System.Diagnostics.Stopwatch de código gerenciado.

using System.Diagnostics;

long StartingTime = Stopwatch.GetTimestamp();

// Activity to be timed

long EndingTime  = Stopwatch.GetTimestamp();
long ElapsedTime = EndingTime - StartingTime;

double ElapsedSeconds = ElapsedTime * (1.0 / Stopwatch.Frequency);

A classe System.Diagnostics.Stopwatch também fornece vários métodos convenientes para executar medidas de intervalo de tempo.

Usando QPC do modo kernel

O kernel do Windows fornece acesso no modo kernel ao contador de desempenho por meio de KeQueryPerformanceCounter do qual o contador de desempenho e a frequência de desempenho podem ser obtidos. KeQueryPerformanceCounter está disponível somente no modo kernel e é fornecido para gravadores de drivers de dispositivo e outros componentes do modo kernel.

Este exemplo mostra como usar KeQueryPerformanceCounter no modo kernel C e C++.

LARGE_INTEGER StartingTime, EndingTime, ElapsedMicroseconds;
LARGE_INTEGER Frequency;

StartingTime = KeQueryPerformanceCounter(&Frequency);

// Activity to be timed

EndingTime = KeQueryPerformanceCounter(NULL);
ElapsedMicroseconds.QuadPart = EndingTime.QuadPart - StartingTime.QuadPart;
ElapsedMicroseconds.QuadPart *= 1000000;
ElapsedMicroseconds.QuadPart /= Frequency.QuadPart;

Perguntas frequentes gerais sobre QPC e TSC

Aqui estão as respostas para perguntas frequentes sobre QPC e TSCs em geral.

QueryPerformanceCounter() é igual à função Win32 GetTickCount() ou GetTickCount64() ?

Não. GetTickCount e GetTickCount64 não estão relacionados ao QPC. GetTickCount e GetTickCount64 retornam o número de milissegundos desde que o sistema foi iniciado.

Devo usar qpc ou chamar as instruções RDTSC/RDTSCP diretamente?

Para evitar problemas de incorretaidade e portabilidade, recomendamos que você use qpc em vez de usar o registro TSC ou as instruções do processador RDTSC ou RDTSCP .

Qual é a relação do QPC com uma época de tempo externo? Ele pode ser sincronizado com uma época externa, como UTC?

O QPC é baseado em um contador de hardware que não pode ser sincronizado com uma referência de tempo externo, como UTC. Para carimbos de data/hora precisos que podem ser sincronizados com uma referência UTC externa, use GetSystemTimePreciseAsFileTime.

O QPC é afetado pelo horário de verão, segundos bissextos, fusos horários ou alterações de horário do sistema feitas pelo administrador?

Não. O QPC é completamente independente da hora do sistema e utc.

A precisão do QPC é afetada pelas alterações de frequência do processador causadas pelo gerenciamento de energia ou pela tecnologia Turbo Boost?

Não. Se o processador tiver um TSC invariável, o QPC não será afetado por esse tipo de alteração. Se o processador não tiver um TSC invariável, o QPC reverter a um temporizador de hardware de plataforma que não será afetado pelas alterações de frequência do processador ou pela tecnologia Turbo Boost.

O QPC funciona de forma confiável em sistemas multiprocessador, sistema multi-core e sistemas com hyper-threading?

Sim.

Como fazer determinar e validar se o QPC funciona no meu computador?

Você não precisa executar essas verificações.

Quais processadores têm TSCs não invariáveis? Como posso marcar se meu sistema tem um TSC não invariável?

Você não precisa executar essa marcar por conta própria. Os sistemas operacionais Windows executam várias verificações na inicialização do sistema para determinar se o TSC é adequado como base para QPC. No entanto, para fins de referência, você pode determinar se o processador tem um TSC invariável usando um destes:

  • o utilitário Coreinfo.exe do Windows Sysinternals
  • verificando os valores retornados pela instrução CPUID referente às características do TSC
  • documentação do fabricante do processador

Veja a seguir as informações TSC-INVARIANT fornecidas pelo utilitário de Coreinfo.exe do Windows Sysinternals (www.sysinternals.com). Um asterisco significa "True".

> Coreinfo.exe 

Coreinfo v3.2 - Dump information on system CPU and memory topology
Copyright (C) 2008-2012 Mark Russinovich
Sysinternals - www.sysinternals.com

 <unrelated text removed>

RDTSCP          * Supports RDTSCP instruction
TSC             * Supports RDTSC instruction
TSC-DEADLINE    - Local APIC supports one-shot deadline timer
TSC-INVARIANT   * TSC runs at constant rate

O QPC funciona de forma confiável em Windows RT plataformas de hardware?

Sim.

Com que frequência o QPC é substituído?

Não menos de 100 anos após a inicialização mais recente do sistema e potencialmente mais longo com base no temporizador de hardware subjacente usado. Para a maioria dos aplicativos, a substituição não é uma preocupação.

Qual é o custo computacional de chamar QPC?

O custo de chamada computacional do QPC é determinado principalmente pela plataforma de hardware subjacente. Se o registro TSC for usado como base para QPC, o custo computacional será determinado principalmente pelo tempo que o processador leva para processar uma instrução RDTSC . Esse tempo varia de 10s de ciclos de CPU a várias centenas de ciclos de CPU, dependendo do processador usado. Se o TSC não puder ser usado, o sistema selecionará uma base de tempo de hardware diferente. Como essas bases de tempo estão localizadas na placa-mãe (por exemplo, na PCI South Bridge ou PCH), o custo computacional por chamada é maior do que o TSC e é frequentemente próximo de 0,8 a 1,0 microssegundos, dependendo da velocidade do processador e de outros fatores de hardware. Esse custo é dominado pelo tempo necessário para acessar o dispositivo de hardware na placa-mãe.

O QPC requer uma transição de kernel (chamada do sistema)?

Uma transição de kernel não será necessária se o sistema puder usar o registro TSC como base para QPC. Se o sistema precisar usar uma base de tempo diferente, como o temporizador HPET ou PM, uma chamada do sistema será necessária.

O contador de desempenho é monotônico (não diminuindo)?

Sim. O QPC não retrocede.

O contador de desempenho pode ser usado para ordenar eventos a tempo?

Sim. No entanto, ao comparar os resultados do contador de desempenho adquiridos de threads diferentes, os valores que diferem por ± 1 tique têm uma ordenação ambígua como se tivessem um carimbo de data/hora idêntico.

Qual é a precisão do contador de desempenho?

A resposta depende de uma variedade de fatores. Para obter mais informações, consulte Características de relógio de hardware de baixo nível.

Perguntas frequentes sobre programação com QPC e TSC

Aqui estão as respostas para perguntas frequentes sobre programação com QPC e TSCs.

Preciso converter a saída de QPC em milissegundos. Como evitar a perda de precisão com a conversão em double ou float?

Há várias coisas a ter em mente ao executar cálculos em contadores de desempenho inteiros:

  • A divisão de inteiros perderá o restante. Isso pode causar perda de precisão em alguns casos.
  • A conversão entre inteiros de 64 bits e ponto flutuante (duplo) pode causar perda de precisão porque a mantissa de ponto flutuante não pode representar todos os valores integrais possíveis.
  • Multiplicação de inteiros de 64 bits pode resultar em estouro de inteiro.

Como princípio geral, atrase esses cálculos e conversões o máximo possível para evitar a computação dos erros introduzidos.

Como posso converter tiques de QPC em 100 nanossegundos para que eu possa adicioná-lo a um FILETIME?

Um tempo de arquivo é um valor de 64 bits que representa o número de intervalos de 100 nanossegundos decorridos desde 12:00 da manhã de 1º de janeiro de 1601 UTC (Tempo Universal Coordenado). Os tempos de arquivo são usados por chamadas à API do Win32 que retornam a hora do dia, como GetSystemTimeAsFileTime e GetSystemTimePreciseAsFileTime. Por outro lado, QueryPerformanceCounter retorna valores que representam o tempo em unidades de 1/(a frequência do contador de desempenho obtido de QueryPerformanceFrequency). A conversão entre os dois requer o cálculo da proporção do intervalo QPC e dos intervalos de 100 nanossegundos. Tenha cuidado para evitar a perda de precisão porque os valores podem ser pequenos (0,0000001/0,000000340).

Por que o carimbo de data/hora retornado do QPC é um inteiro com sinal?

Cálculos que envolvem carimbos de data/hora de QPC podem envolver subtração. Usando um valor assinado, você pode lidar com cálculos que podem gerar valores negativos.

Como posso obter carimbos de data/hora de alta resolução do código gerenciado?

Chame o método Stopwatch.GetTimeStamp da classe System.Diagnostics.Stopwatch . Para obter um exemplo sobre como usar Stopwatch.GetTimeStamp, consulte Adquirindo carimbos de data/hora de alta resolução do código gerenciado.

Em que circunstâncias QueryPerformanceFrequency retorna FALSE ou QueryPerformanceCounter retorna zero?

Isso não ocorrerá em nenhum sistema que execute o Windows XP ou posterior.

Preciso definir a afinidade de thread para um único núcleo para usar o QPC?

Não. Para obter mais informações, consulte Diretrizes para adquirir carimbos de data/hora. Esse cenário não é necessário nem desejável. A execução desse cenário pode afetar negativamente o desempenho do aplicativo restringindo o processamento a um núcleo ou criando um gargalo em um único núcleo se vários threads definirem sua afinidade com o mesmo núcleo ao chamar QueryPerformanceCounter.

Características de relógio de hardware de baixo nível

Essas seções mostram características de relógio de hardware de baixo nível.

Relógios absolutos e relógios de diferença

Relógios absolutos fornecem leituras precisas da hora do dia. Normalmente, eles são baseados em UTC (Tempo Universal Coordenado) e, consequentemente, sua precisão depende, em parte, de quão bem eles são sincronizados com uma referência de tempo externo. Os relógios de diferença medem intervalos de tempo e normalmente não são baseados em uma época de tempo externa. O QPC é um relógio de diferença e não é sincronizado com uma época ou referência externa. Ao usar o QPC para medidas de intervalo de tempo, você normalmente obtém uma precisão melhor do que obteria usando carimbos de data/hora derivados de um relógio absoluto. Isso ocorre porque o processo de sincronização da hora de um relógio absoluto pode introduzir mudanças de fase e frequência que aumentam a incerteza das medidas de intervalo de tempo de curto prazo.

Resolução, precisão, precisão e estabilidade

O QPC usa um contador de hardware como base. Os temporizadores de hardware consistem em três partes: um gerador de escala, um contador que conta os tiques e um meio de recuperar o valor do contador. As características desses três componentes determinam a resolução, precisão, precisão e estabilidade do QPC.

Se um gerador de hardware fornecer tiques a uma taxa constante, os intervalos de tempo poderão ser medidos simplesmente contando esses tiques. A taxa na qual os tiques são gerados é chamada de frequência e expressa em Hertz (Hz). A recíproca da frequência é chamada de período ou intervalo de escala e é expressa em uma unidade de tempo apropriada do SISTEMA Internacional de Unidades (SI) (por exemplo, segundo, milissegundo, microssegundo ou nanossegundo).

intervalo de tempo

A resolução do temporizador é igual ao período. A resolução determina a capacidade de distinguir entre dois carimbos de data/hora e coloca um limite inferior nos menores intervalos de tempo que podem ser medidos. Às vezes, isso é chamado de resolução de tique.

A medição digital do tempo introduz uma incerteza de medidas de ± 1 tique porque o contador digital avança em etapas discretas, enquanto o tempo está avançando continuamente. Essa incerteza é chamada de erro de quantização. Para medidas típicas de intervalo de tempo, esse efeito geralmente pode ser ignorado porque o erro de quantificação é muito menor do que o intervalo de tempo que está sendo medido.

medição de tempo digital

No entanto, se o período que está sendo medido for pequeno e se aproximar da resolução do temporizador, você precisará considerar esse erro de quantificação. O tamanho do erro introduzido é o de um período de relógio.

Os dois diagramas a seguir ilustram o impacto da incerteza de escala ± 1 usando um temporizador com uma resolução de uma unidade de tempo.

incerteza de escala

QueryPerformanceFrequency retorna a frequência de QPC e o período e a resolução são iguais ao recíproco desse valor. A frequência do contador de desempenho que QueryPerformanceFrequency retorna é determinada durante a inicialização do sistema e não é alterada enquanto o sistema está em execução.

Observação

Geralmente , QueryPerformanceFrequency não retorna a frequência real do gerador de tiques de hardware. Por exemplo, em algumas versões mais antigas do Windows, QueryPerformanceFrequency retorna a frequência TSC dividida por 1024; e ao executar em um hipervisor que implementa a interface do hipervisor versão 1.0 (ou sempre em algumas versões mais recentes do Windows), a frequência do contador de desempenho é fixada em 10 MHz. Como resultado, não suponha que QueryPerformanceFrequency retornará um valor derivado da frequência de hardware.

 

QueryPerformanceCounter lê o contador de desempenho e retorna o número total de tiques que ocorreram desde que o sistema operacional Windows foi iniciado, incluindo a hora em que o computador estava em estado de suspensão, como espera, hibernação ou modo de espera conectado.

Esses exemplos mostram como calcular o intervalo de escala e a resolução e como converter a contagem de tiques em um valor de tempo.

Exemplo 1

QueryPerformanceFrequency retorna o valor 3.125.000 em um computador específico. Qual é o intervalo de escala e a resolução de medidas de QPC neste computador? O intervalo de escala, ou período, é o recíproco de 3.125.000, que é 0,000000320 (320 nanossegundos). Portanto, cada tique representa a passagem de 320 nanossegundos. Intervalos de tempo menores que 320 nanossegundos não podem ser medidos neste computador.

Intervalo de escala = 1/(Frequência de Desempenho)

Intervalo de escala = 1/3.125.000 = 320 ns

Exemplo 2

No mesmo computador que o exemplo anterior, a diferença dos valores retornados de duas chamadas sucessivas para QPC é 5. Quanto tempo se passou entre as duas chamadas? 5 tiques multiplicados por 320 nanossegundos produzem 1,6 microssegundos.

ElapsedTime = Ticks * Tick Interval

ElapsedTime = 5 * 320 ns = 1,6 μs

Leva tempo para acessar (ler) o contador de tiques do software, e esse tempo de acesso pode reduzir a precisão da medida de tempo. Isso ocorre porque o tempo mínimo de intervalo (o menor intervalo de tempo que pode ser medido) é o maior da resolução e do tempo de acesso.

Precision = MAX [ Resolution, AccessTime]

Por exemplo, considere um temporizador de hardware hipotético com uma resolução de 100 nanossegundos e um tempo de acesso de 800 nanossegundos. Esse pode ser o caso se o temporizador de plataforma tiver sido usado em vez do registro TSC como base do QPC. Portanto, a precisão seria de 800 nanossegundos e não 100 nanossegundos, conforme mostrado neste cálculo.

Precision = MAX [800 ns,100 ns] = 800 ns

Essas duas figuras retratam esse efeito.

hora de acesso do qpc

Se o tempo de acesso for maior que a resolução, não tente melhorar a precisão adivinhando. Em outras palavras, é um erro assumir que o carimbo de data/hora é usado precisamente no meio ou no início ou no final da chamada.

Por outro lado, considere o exemplo a seguir no qual o tempo de acesso de QPC é de apenas 20 nanossegundos e a resolução do relógio de hardware é de 100 nanossegundos. Esse pode ser o caso se o registro TSC foi usado como base para QPC. Aqui, a precisão é limitada pela resolução do relógio.

precisão de qpc

Na prática, você pode encontrar fontes de tempo para as quais o tempo necessário para ler o contador é maior ou menor que a resolução. Em ambos os casos, a precisão será maior entre os dois.

Esta tabela fornece informações sobre a resolução aproximada, o tempo de acesso e a precisão de uma variedade de relógios. Observe que alguns dos valores variam com processadores, plataformas de hardware e velocidades de processador diferentes.

Origem do Relógio Frequência nominal do relógio Resolução do relógio Hora de Acesso (Típico) Precisão
PC RTC 64 Hz 15,625 milissegundos N/D N/D
Contador de desempenho de consulta usando TSC com um relógio de processador de 3 GHz 3 MHz 333 nanossegundos 30 nanossegundos 333 nanossegundos
Instrução do computador RDTSC em um sistema com um tempo de ciclo de 3 GHz 3 GHz 333 picoseconds 30 nanossegundos 30 nanossegundos

 

Como o QPC usa um contador de hardware, quando você entende algumas características básicas dos contadores de hardware, obtém compreensão sobre as funcionalidades e limitações do QPC.

O gerador de tique de hardware mais usado é um oscilador de cristal. O cristal é um pequeno pedaço de quartzo ou outro material cerâmico que exibe características piezoelétricas que fornecem uma referência de frequência barata com excelente estabilidade e precisão. Essa frequência é usada para gerar os tiques contados pelo relógio.

A precisão de um temporizador refere-se ao grau de conformidade a um valor verdadeiro ou padrão. Isso depende principalmente da capacidade do oscilador de cristal de fornecer tiques na frequência especificada. Se a frequência de oscilação for muito alta, o relógio "será executado rapidamente" e os intervalos medidos aparecerão por mais tempo do que realmente são; e se a frequência for muito baixa, o relógio "ficará lento", e os intervalos medidos aparecerão mais curtos do que realmente são.

Para medidas típicas de intervalo de tempo por curta duração (por exemplo, medidas de tempo de resposta, medidas de latência de rede e assim por diante), a precisão do oscilador de hardware geralmente é suficiente. No entanto, para algumas medidas, a precisão da frequência do oscilador torna-se importante, especialmente para intervalos de tempo longos ou quando você deseja comparar medidas feitas em computadores diferentes. O restante desta seção explora os efeitos da precisão do oscilador.

A frequência de oscilação dos cristais é definida durante o processo de fabricação e é especificada pelo fabricante em termos de uma frequência especificada mais ou menos uma tolerância de fabricação expressa em "partes por milhão" (ppm), chamada de deslocamento de frequência máxima. Um cristal com uma frequência especificada de 1.000.000 Hz e um deslocamento de frequência máxima de ± 10 ppm estaria dentro dos limites de especificação se sua frequência real estivesse entre 999.990 Hz e 1.000.010 Hz.

Ao substituir as partes de frase por milhão por microssegundos por segundo, podemos aplicar esse erro de deslocamento de frequência a medidas de intervalo de tempo. Um oscilador com um deslocamento + 10 ppm teria um erro de 10 microssegundos por segundo. Assim, ao medir um intervalo de 1 segundo, ele seria executado rapidamente e mediria um intervalo de 1 segundo como 0,9999990 segundos.

Uma referência conveniente é que um erro de frequência de 100 ppm causa um erro de 8,64 segundos após 24 horas. Esta tabela apresenta a incerteza de medição devido ao erro acumulado para intervalos de tempo mais longos.

Duração do intervalo de tempo Incerteza de medição devido a um erro acumulado com tolerância de frequência de +/- 10 PPM
1 microssegundo ± 10 picoseconds (10-12)
1 milissegundo ± 10 nanossegundos (10-9)
1 segundo ± 10 microssegundos
1 hora ± 60 microssegundos
1 dia ± 0,86 segundos
Uma semana ± 6,08 segundos

 

A tabela anterior mostra que, para intervalos de tempo pequenos, o erro de deslocamento de frequência geralmente pode ser ignorado. No entanto, para intervalos de tempo longos, mesmo um pequeno deslocamento de frequência pode resultar em uma incerteza de medida substancial.

Os osciladores de cristal usados em computadores pessoais e servidores normalmente são fabricados com uma tolerância de frequência de ± de 30 a 50 partes por milhão e, raramente, os cristais podem estar desativados em até 500 ppm. Embora os cristais com tolerâncias de deslocamento de frequência muito mais rígidas estejam disponíveis, eles são mais caros e, portanto, não são usados na maioria dos computadores.

Para reduzir os efeitos adversos desse erro de deslocamento de frequência, as versões recentes do Windows, particularmente Windows 8, usam vários temporizadores de hardware para detectar o deslocamento de frequência e compensá-lo na medida do possível. Esse processo de calibragem é executado quando o Windows é iniciado.

Como mostram os exemplos a seguir, o erro de deslocamento de frequência de um relógio de hardware influencia a precisão alcançável e a resolução do relógio pode ser menos importante.

O erro de deslocamento de frequência influencia a precisão alcançável

Exemplo 1

Suponha que você execute medidas de intervalo de tempo usando um oscilador de 1 MHz, que tem uma resolução de 1 microssegundo e um erro de deslocamento de frequência máxima de ±50 ppm. Agora, vamos supor que o deslocamento seja exatamente +50 ppm. Isso significa que a frequência real seria de 1.000.050 Hz. Se medimos um intervalo de tempo de 24 horas, nossa medição seria 4,3 segundos muito curta (23:59:55.700000 medida versus 24:00:00.00000 real).

Segundos em um dia = 86400

Erro de deslocamento de frequência = 50 ppm = 0,00005

86.400 segundos * 0,00005 = 4,3 segundos

Exemplo 2

Suponha que o relógio TSC do processador seja controlado por um oscilador de cristal e tenha uma frequência especificada de 3 GHz. Isso significa que a resolução seria de 1/3.000.000.000 ou cerca de 333 picoseconds. Suponha que o cristal usado para controlar o relógio do processador tenha uma tolerância de frequência de ±50 ppm e na verdade seja +50 ppm. Apesar da resolução impressionante, uma medição de intervalo de tempo de 24 horas ainda será 4,3 segundos muito curta. (23:59:55.70000000000 medido versus 24:00:00:00.0000000000 real).

Segundos em um dia = 86400

Erro de deslocamento de frequência = 50 ppm = 0,00005

86.400 segundos * 0,00005 = 4,3 segundos

Isso mostra que um relógio TSC de alta resolução não fornece necessariamente medidas mais precisas do que um relógio de resolução mais baixa.

Exemplo 3

Considere usar dois computadores diferentes para medir o mesmo intervalo de tempo de 24 horas. Ambos os computadores têm um oscilador com um deslocamento de frequência máxima de ± 50 ppm. Quão distante pode ser a medição do mesmo intervalo de tempo nesses dois sistemas? Como nos exemplos anteriores, ± 50 ppm gera um erro máximo de ± 4,3 segundos após 24 horas. Se um sistema for executado 4,3 segundos rapidamente e os outros 4,3 segundos forem lentos, o erro máximo após 24 horas poderá ser de 8,6 segundos.

Segundos em um dia = 86400

Erro de deslocamento de frequência = ±50 ppm = ±0,00005

±(86.400 segundos * 0,00005) = ±4,3 segundos

Deslocamento máximo entre os dois sistemas = 8,6 segundos

Em resumo, o erro de deslocamento de frequência torna-se cada vez mais importante ao medir intervalos de tempo longos e ao comparar medidas entre sistemas diferentes.

A estabilidade de um temporizador descreve se a frequência do tique muda ao longo do tempo, por exemplo, à medida que o resultado das temperaturas muda. Cristais de quartzo usados como geradores de carrapatos em computadores apresentarão pequenas mudanças de frequência como função da temperatura. O erro causado pelo descompasso térmico normalmente é pequeno em comparação com o erro de deslocamento de frequência para intervalos de temperatura comuns. No entanto, os designers de software para equipamentos portáteis ou equipamentos sujeitos a grandes flutuações de temperatura podem precisar considerar esse efeito.

Informações do temporizador de hardware

Registro TSC (x86 e x64)

Todos os processadores Intel e AMD modernos contêm um registro TSC que é um registro de 64 bits que aumenta a uma taxa alta, normalmente igual ao relógio do processador. O valor desse contador pode ser lido por meio das instruções do computador RDTSC ou RDTSCP , fornecendo um tempo de acesso muito baixo e custo computacional na ordem de dezenas ou centenas de ciclos de computador, dependendo do processador.

Embora o registro TSC pareça um mecanismo de carimbo de data/hora ideal, aqui estão as circunstâncias em que ele não pode funcionar de forma confiável para fins de manutenção de tempo:

  • Nem todos os processadores têm registros TSC utilizáveis, portanto, o uso do registro TSC no software cria diretamente um problema de portabilidade. (O Windows selecionará uma fonte de tempo alternativa para QPC nesse caso, o que evita o problema de portabilidade.)
  • Alguns processadores podem variar a frequência do relógio TSC ou interromper o avanço do registro TSC, o que torna o TSC inadequado para fins de tempo nesses processadores. Dizem que esses processadores têm registros TSC não invariáveis. (O Windows detectará isso automaticamente e selecionará uma fonte de tempo alternativa para QPC).
  • Mesmo que um host de virtualização tenha um TSC utilizável, a migração dinâmica de máquinas virtuais em execução quando o host de virtualização de destino não tiver ou utilizar o dimensionamento de TSC assistido por hardware poderá resultar em uma alteração na frequência TSC visível para os convidados. (Espera-se que, se esse tipo de migração dinâmica for possível para um convidado, que o hipervisor limpe o bit de recurso TSC invariável em CPUID.)
  • Em sistemas multiprocessador ou de vários núcleos, alguns processadores e sistemas não conseguem sincronizar os relógios em cada núcleo com o mesmo valor. (O Windows detectará isso automaticamente e selecionará uma fonte de tempo alternativa para QPC).
  • Em alguns sistemas de vários processadores grandes, talvez você não consiga sincronizar os relógios do processador com o mesmo valor, mesmo que o processador tenha um TSC invariável. (O Windows detectará isso automaticamente e selecionará uma fonte de tempo alternativa para QPC).
  • Alguns processadores executarão instruções fora de ordem. Isso pode resultar em contagens de ciclo incorretas quando o RDTSC é usado para cronometrar sequências de instruções porque a instrução RDTSC pode ser executada em um momento diferente do especificado em seu programa. A instrução RDTSCP foi introduzida em alguns processadores em resposta a esse problema.

Como outros temporizadores, o TSC é baseado em um oscilador de cristal cuja frequência exata não é conhecida com antecedência e que tem um erro de deslocamento de frequência. Portanto, antes de poder ser usado, ele deve ser calibrado usando outra referência de tempo.

Durante a inicialização do sistema, o Windows verifica se o TSC é adequado para fins de tempo e executa a calibragem de frequência e a sincronização principal necessárias.

Relógio PM (x86 e x64)

O temporizador ACPI, também conhecido como relógio PM, foi adicionado à arquitetura do sistema para fornecer carimbos de data/hora confiáveis independentemente da velocidade dos processadores. Como esse era o único objetivo desse temporizador, ele fornece um carimbo de data/hora em um único ciclo de relógio, mas não fornece nenhuma outra funcionalidade.

Temporizador HPET (x86 e x64)

O HPET (Timer de Eventos de Alta Precisão) foi desenvolvido em conjunto pela Intel e pela Microsoft para atender aos requisitos de tempo de multimídia e outros aplicativos sensíveis ao tempo. Ao contrário do TSC, que é um recurso por processador, o HPET é um recurso compartilhado em toda a plataforma, embora um sistema possa ter vários HPETs. O suporte a HPET está no Windows desde o Windows Vista, e a certificação do Logotipo de Hardware do Windows 7 e Windows 8 requer suporte a HPET na plataforma de hardware.

Contador de sistema de temporizador genérico (Arm)

As plataformas baseadas em Arm não têm um relógio TSC, HPET ou PM, como há em plataformas baseadas em Intel ou AMD. Em vez disso, os processadores Arm fornecem o Temporizador Genérico (às vezes chamado de Temporizador de Intervalo Genérico ou GIT), que contém um registro de Contador do Sistema (por exemplo, CNTVCT_EL0). O Contador de Sistema de Temporizador Genérico é uma fonte de tempo em toda a plataforma de frequência fixa. Ele começa em zero na inicialização e aumenta a uma taxa alta. No Armv8.6 ou superior, isso é definido como exatamente 1 GHz, mas deve ser determinado lendo o registro de frequência do relógio que é definido pelo firmware de inicialização antecipada. Para obter mais detalhes, confira o capítulo "O Temporizador Genérico no estado AArch64" em "Manual de Referência de Arquitetura do Arm para arquitetura de perfil A" (DDI 0487).

Contador de ciclo (Arm)

As plataformas baseadas em Arm fornecem um registro de Contador de Ciclo de Monitores de Desempenho (por exemplo, PMCCNTR_EL0). Esse contador conta os ciclos de relógio do processador. Não é invariável e suas unidades podem não estar correlacionadas ao tempo real. Não é recomendável usar esse registro para obter carimbos de data/hora.