Acquisizione di timestamp ad alta risoluzione

Windows fornisce API che è possibile usare per acquisire timestamp ad alta risoluzione o intervalli di tempo di misura. L'API primaria per il codice nativo è QueryPerformanceCounter (QPC). Per i driver di dispositivo, l'API in modalità kernel è KeQueryPerformanceCounter. Per il codice gestito, la classe System.Diagnostics.Stopwatch usa QPC come base temporale precisa.

QPC è indipendente da e non è sincronizzato con qualsiasi riferimento all'ora esterna. Per recuperare i timestamp che possono essere sincronizzati con un riferimento all'ora esterna, ad esempio l'ora UTC (Coordinated Universal Time) per l'uso nelle misurazioni a risoluzione elevata, usare GetSystemTimePreciseAsFileTime.

I timestamp e le misurazioni a intervalli di tempo sono parte integrante delle misurazioni delle prestazioni del computer e della rete. Queste operazioni di misurazione delle prestazioni includono il calcolo del tempo di risposta, della velocità effettiva e della latenza, nonché l'esecuzione del codice di profilatura. Ognuna di queste operazioni comporta una misurazione delle attività che si verificano durante un intervallo di tempo definito da un inizio e un evento finale che può essere indipendente da qualsiasi riferimento esterno.

QPC è in genere il metodo migliore da usare per gli eventi timestamp e misurare piccoli intervalli di tempo che si verificano nello stesso sistema o macchina virtuale. Prendere in considerazione l'uso di GetSystemTimePreciseAsFileTime quando si desidera eseguire il timestamp di eventi in più computer, a condizione che ogni computer stia partecipando a uno schema di sincronizzazione temporale, ad esempio Il protocollo NTP (Network Time Protocol). QPC consente di evitare difficoltà che possono essere rilevate con altri approcci di misurazione del tempo, ad esempio la lettura diretta del contatore del timestamp del processore.

Supporto QPC nelle versioni di Windows

QPC è stato introdotto in Windows 2000 e Windows XP e si è evoluto per sfruttare i miglioramenti della piattaforma hardware e dei processori. In questo articolo vengono descritte le caratteristiche di QPC in versioni diverse di Windows per consentire di mantenere il software in esecuzione in tali versioni di Windows.

Windows XP e Windows 2000

QPC è disponibile in Windows XP e Windows 2000 e funziona bene nella maggior parte dei sistemi. Tuttavia, il BIOS di alcuni sistemi hardware non indicava correttamente le caratteristiche della CPU hardware (un TSC non invariante) e alcuni sistemi multi-core o multi-processori usati con processori con TSC che non potevano essere sincronizzati tra core. I sistemi con firmware difettoso che eseguono queste versioni di Windows potrebbero non fornire la stessa lettura QPC in core diversi se hanno usato il TSC come base per QPC.

Windows Vista e Windows Server 2008

Tutti i computer forniti con Windows Vista e Windows Server 2008 hanno usato un contatore della piattaforma (Timer eventi ad alta precisione (HPET) o il timer di gestione energia ACPI (timer PM) come base per QPC. Tali timer della piattaforma hanno una latenza di accesso maggiore rispetto al TSC e sono condivisi tra più processori. Questo limita la scalabilità del QPC se viene chiamato simultaneamente da più processori.

Windows 7 e Windows Server 2008 R2

La maggior parte dei computer Windows 7 e Windows Server 2008 R2 hanno processori con TSC a frequenza costante e usano questi contatori come base per QPC. I controller di rete sono contatori hardware ad alta risoluzione per processore a cui è possibile accedere con una latenza e un sovraccarico molto bassi (in ordine di 10 o 100 cicli di computer, a seconda del tipo di processore). Windows 7 e Windows Server 2008 R2 usano le schede di rete come base di QPC nei sistemi di dominio a orologio singolo in cui il sistema operativo (o l'hypervisor) è in grado di sincronizzare strettamente i singoli controller di rete in tutti i processori durante l'inizializzazione del sistema. In tali sistemi, il costo di lettura del contatore delle prestazioni è notevolmente inferiore rispetto ai sistemi che usano un contatore della piattaforma. Inoltre, non è stato aggiunto alcun sovraccarico per le chiamate simultanee e le query in modalità utente spesso ignorano le chiamate di sistema, riducendo ulteriormente il sovraccarico. Nei sistemi in cui il TSC non è adatto per il tempo di conservazione, Windows seleziona automaticamente un contatore della piattaforma (il timer HPET o il timer ACPI PM) come base per 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 usano le schede di rete come base per il contatore delle prestazioni. L'algoritmo di sincronizzazione TSC è stato notevolmente migliorato per soddisfare meglio sistemi di grandi dimensioni con molti processori. Inoltre, è stato aggiunto il supporto per la nuova API temporale precisa, che consente di acquisire indicatori di ora del muro precisi dal sistema operativo. Per altre informazioni, vedere GetSystemTimePreciseAsFileTime. In Windows RT e Windows 11 e Windows 10 dispositivi che usano processori Arm, il contatore delle prestazioni si basa su un contatore della piattaforma proprietario o sul contatore del sistema fornito dal timer generico arm se la piattaforma è così dotata.

Linee guida per l'acquisizione di timestamp

Windows ha e continuerà a investire nel fornire un contatore delle prestazioni affidabile ed efficiente. Quando sono necessari timestamp con una risoluzione di 1 microsecondo o superiore e non è necessario sincronizzare i timestamp in un riferimento temporale esterno, scegliere QueryPerformanceCounter, KeQueryPerformanceCounter o KeQueryInterruptTimePrecise. Quando sono necessari timestamp sincronizzati UTC con una risoluzione di 1 microsecondo o superiore, scegliere GetSystemTimePreciseAsFileTime o KeQuerySystemTimePrecise.

In un numero relativamente ridotto di piattaforme che non possono usare il registro TSC come base QPC , ad esempio, per motivi spiegati in Informazioni timer hardware, l'acquisizione di timestamp ad alta risoluzione può essere significativamente più costosa rispetto all'acquisizione di timestamp con una risoluzione inferiore. Se la risoluzione di 10-16 millisecondi è sufficiente, è possibile usare GetTickCount64, QueryInterruptTime, QueryUnbiasedInterruptTime, KeQueryInterruptTime o KeQueryUnbiasedInterruptTime per ottenere i timestamp non sincronizzati con un riferimento temporale esterno. Per i timestamp sincronizzati UTC, usare GetSystemTimeAsFileTime o KeQuerySystemTime. Se è necessaria una risoluzione superiore, è possibile usare QueryInterruptTimePrecise, QueryUnbiasedInterruptTimePrecise o KeQueryInterruptTimePrecise per ottenere i timestamp.

In generale, i risultati del contatore delle prestazioni sono coerenti tra tutti i processori in sistemi multi-core e multi-processor, anche se misurati su thread o processi diversi. Ecco alcune eccezioni a questa regola:

  • I sistemi operativi pre-Windows Vista eseguiti su determinati processori potrebbero violare questa coerenza a causa di uno di questi motivi:

    • I processori hardware hanno un TSC non invariante e il BIOS non indica correttamente questa condizione.
    • L'algoritmo di sincronizzazione TSC usato non era adatto per i sistemi con un numero elevato di processori.
  • Quando si confrontano i risultati del contatore delle prestazioni acquisiti da thread diversi, considerare i valori che differiscono ± 1 tick per avere un ordinamento ambiguo. Se i timestamp vengono presi dallo stesso thread, questa ± 1 incertezza di tick non viene applicata. In questo contesto, il termine tick fa riferimento a un periodo di tempo uguale a 1 ÷ (la frequenza del contatore delle prestazioni ottenuta da QueryPerformanceFrequency).

Quando si usa il contatore delle prestazioni in sistemi server di grandi dimensioni con domini di più orologi non sincronizzati nell'hardware, Windows determina che il TSC non può essere usato per scopi di intervallo e seleziona un contatore della piattaforma come base per QPC. Anche se questo scenario restituisce ancora timestamp affidabili, la latenza di accesso e scalabilità è danneggiata in modo negativo. Pertanto, come indicato in precedenza nelle linee guida sull'utilizzo precedenti, usare solo le API che forniscono 1 microsecondo o una risoluzione migliore quando tale risoluzione è necessaria. Il TSC viene usato come base per QPC nei sistemi di dominio multi-clock che includono la sincronizzazione hardware di tutti i domini dell'orologio del processore, in modo che funzionino in modo efficace come un singolo sistema di dominio dell'orologio.

La frequenza del contatore delle prestazioni è fissa all'avvio del sistema ed è coerente in tutti i processori, quindi è sufficiente eseguire una query sulla frequenza da QueryPerformanceFrequency come inizializza l'applicazione e quindi memorizzare nella cache il risultato.

Virtualizzazione

Il contatore delle prestazioni dovrebbe funzionare in modo affidabile su tutte le macchine virtuali guest in esecuzione in hypervisor correttamente implementati. Tuttavia, gli hypervisor conformi all'interfaccia hypervisor versione 1.0 e superficieno l'illuminazione temporale di riferimento possono offrire un sovraccarico notevolmente inferiore. Per altre informazioni sulle interfacce e le funzioni di illuminazione dell'hypervisor, vedere Specifiche di Hypervisor.

Utilizzo TSC diretto

È consigliabile usare l'istruzione del processore RDTSC o RDTSCP per eseguire direttamente query sul TSC perché non si otterranno risultati affidabili in alcune versioni di Windows, tra migrazioni in tempo reale di macchine virtuali e nei sistemi hardware senza invarianti o sincronizzati strettamente. È invece consigliabile usare QPC per sfruttare l'astrazione, la coerenza e la portabilità offerte.

Esempi per l'acquisizione di timestamp

I vari esempi di codice in queste sezioni illustrano come acquisire timestamp.

Uso di QPC nel codice nativo

Questo esempio illustra come usare QPC nel codice 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;

Acquisizione di timestamp ad alta risoluzione dal codice gestito

In questo esempio viene illustrato come usare la classe System.Diagnostics.Stopwatch del codice gestito.

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);

La classe System.Diagnostics.Stopwatch offre anche diversi metodi pratici per eseguire misurazioni a intervalli di tempo.

Uso di QPC dalla modalità kernel

Il kernel di Windows fornisce l'accesso in modalità kernel al contatore delle prestazioni tramite KeQueryPerformanceCounter da cui è possibile ottenere sia il contatore delle prestazioni che la frequenza delle prestazioni. KeQueryPerformanceCounter è disponibile solo in modalità kernel e viene fornito per writer di driver di dispositivo e altri componenti in modalità kernel.

Questo esempio illustra come usare KeQueryPerformanceCounter in modalità 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;

Domande frequenti generali su QPC e TSC

Ecco le risposte alle domande frequenti su QPC e TSC in generale.

QueryPerformanceCounter() è uguale alla funzione Win32 GetTickCount() o GetTickCount64() ?

No. GetTickCount e GetTickCount64 non sono correlati a QPC. GetTickCount e GetTickCount64 restituiscono il numero di millisecondi dall'avvio del sistema.

È consigliabile usare QPC o chiamare direttamente le istruzioni RDTSC/RDTSCP?

Per evitare problemi di correttezza e portabilità, è consigliabile usare QPC anziché usare il registro TSC o le istruzioni del processore RDTSC o RDTSCP.

Qual è la relazione del QPC a un periodo di tempo esterno? Può essere sincronizzato con un'epoca esterna, ad esempio UTC?

QPC è basato su un contatore hardware che non può essere sincronizzato con un riferimento all'ora esterna, ad esempio UTC. Per indicatori temporali precisi che possono essere sincronizzati con un riferimento UTC esterno, usare GetSystemTimePreciseAsFileTime.

QPC è interessato dall'ora legale, dai secondi intercalari, dai fusi orari o dalle modifiche apportate dall'amministratore?

No. QPC è completamente indipendente dall'ora di sistema e dall'ora UTC.

L'accuratezza QPC è influenzata dalle modifiche della frequenza del processore causate dal risparmio energia o dalla tecnologia Turbo Boost?

No. Se il processore ha un TSC invariante, il QPC non è interessato da questi tipi di modifiche. Se il processore non ha un TSC invariante, QPC verrà ripristinato a un timer hardware della piattaforma che non sarà interessato dalle modifiche della frequenza del processore o dalla tecnologia Turbo Boost.

QPC funziona in modo affidabile su sistemi multiprocessore, sistemi multicore e sistemi con hyperthreading?

Sì.

Ricerca per categorie determinare e verificare che QPC funzioni nel computer?

Non è necessario eseguire tali controlli.

Quali processori hanno TSC non invarianti? Come è possibile verificare se il sistema dispone di un TSC non invariante?

Non è necessario eseguire questa verifica manualmente. I sistemi operativi Windows eseguono diversi controlli all'inizializzazione del sistema per determinare se il TSC è adatto come base per QPC. Tuttavia, a scopo di riferimento, è possibile determinare se il processore dispone di un TSC invariante usando uno dei seguenti:

  • utilità Coreinfo.exe da Windows Sysinternals
  • controllo dei valori restituiti dall'istruzione CPUID relativa alle caratteristiche TSC
  • documentazione del produttore del processore

Di seguito vengono illustrate le informazioni TSC-INVARIANT fornite dall'utilità Coreinfo.exe Sysinternals di Windows (www.sysinternals.com). Un 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

QPC funziona in modo affidabile su piattaforme hardware Windows RT?

Sì.

Con quale frequenza viene eseguito il rollover di QPC?

Non meno di 100 anni dall'avvio del sistema più recente e potenzialmente più lungo in base al timer hardware sottostante usato. Per la maggior parte delle applicazioni, il rollover non è un problema.

Qual è il costo di calcolo della chiamata AQPC?

Il costo di chiamata computazionale di QPC viene determinato principalmente dalla piattaforma hardware sottostante. Se il registro TSC viene usato come base per QPC, il costo di calcolo viene determinato principalmente dal tempo impiegato dal processore per elaborare un'istruzione RDTSC . Questo intervallo di tempo varia da 10 cicli di CPU a diverse centinaia di cicli di CPU a seconda del processore usato. Se il TSC non può essere usato, il sistema selezionerà una base temporale hardware diversa. Poiché queste basi temporali si trovano sulla scheda madre (ad esempio, su PCI South Bridge o PCH), il costo di calcolo per chiamata è superiore al TSC e si trova spesso nelle vicinanze di 0,8 - 1,0 microsecondi a seconda della velocità del processore e di altri fattori hardware. Questo costo è dominato dal tempo necessario per accedere al dispositivo hardware sulla scheda madre.

QPC richiede una transizione del kernel (chiamata di sistema)?

Una transizione del kernel non è necessaria se il sistema può usare il registro TSC come base per QPC. Se il sistema deve usare una base temporale diversa, ad esempio il timer HPET o PM, è necessaria una chiamata di sistema.

Il contatore delle prestazioni è monotonico (non decrescente)?

Sì. QPC non va indietro.

Il contatore delle prestazioni può essere usato per ordinare gli eventi nel tempo?

Sì. Tuttavia, quando si confrontano i risultati del contatore delle prestazioni acquisiti da thread diversi, i valori che differiscono per ± 1 tick hanno un ordinamento ambiguo come se avessero un timestamp identico.

Quanto è accurato il contatore delle prestazioni?

La risposta dipende da una varietà di fattori. Per altre info, vedi Caratteristiche dell'orologio hardware di basso livello.

Domande frequenti sulla programmazione con QPC e TSC

Ecco le risposte alle domande frequenti sulla programmazione con QPC e TSC.

È necessario convertire l'output QPC in millisecondi. Come è possibile evitare la perdita di precisione con la conversione in double o float?

Quando si eseguono calcoli sui contatori delle prestazioni integer, tenere presenti diversi aspetti:

  • La divisione integer perderà il resto. Ciò può causare la perdita di precisione in alcuni casi.
  • La conversione tra numeri interi a 64 bit e a virgola mobile (double) può causare una perdita di precisione perché la mantissa a virgola mobile non può rappresentare tutti i valori integrali possibili.
  • La moltiplicazione di interi a 64 bit può comportare un overflow intero.

Come principio generale, ritardare questi calcoli e conversioni il più a lungo possibile per evitare di composto gli errori introdotti.

Come è possibile convertire QPC in tick da 100 nanosecondi in modo da poterlo aggiungere a un FILETIME?

Un'ora di file è un valore a 64 bit che rappresenta il numero di intervalli di 100 nanosecondi trascorsi dalle 12.00 del 1° gennaio 1601 utc (Coordinated Universal Time). I tempi di file vengono usati dalle chiamate API Win32 che restituiscono l'ora del giorno, ad esempio GetSystemTimeAsFileTime e GetSystemTimePreciseAsFileTime. Al contrario, QueryPerformanceCounter restituisce valori che rappresentano il tempo in unità di 1/(la frequenza del contatore delle prestazioni ottenuta da QueryPerformanceFrequency). La conversione tra i due richiede il calcolo del rapporto tra l'intervallo QPC e gli intervalli di 100 nanosecondi. Prestare attenzione a evitare di perdere la precisione perché i valori potrebbero essere piccoli (0,0000001 / 0,000000340).

Perché il timestamp restituito da QPC è un intero con segno?

I calcoli che coinvolgono timestamp QPC potrebbero comportare sottrazione. Usando un valore con segno, è possibile gestire calcoli che potrebbero restituire valori negativi.

Come è possibile ottenere timestamp ad alta risoluzione dal codice gestito?

Chiamare il metodo Stopwatch.GetTimeStamp dalla classe System.Diagnostics.Stopwatch . Per un esempio su come usare Stopwatch.GetTimeStamp, vedere Acquisizione di timestamp ad alta risoluzione dal codice gestito.

In quali circostanze QueryPerformanceFrequency restituisce FALSE o QueryPerformanceCounter restituisce zero?

Questo non si verifica in alcun sistema che esegue Windows XP o versione successiva.

È necessario impostare l'affinità di thread su un singolo core per usare QPC?

No. Per altre info, vedi Linee guida per l'acquisizione di timestamp. Questo scenario non è né necessario né auspicabile. L'esecuzione di questo scenario potrebbe influire negativamente sulle prestazioni dell'applicazione limitando l'elaborazione a un core o creando un collo di bottiglia in un singolo core se più thread impostano la propria affinità sullo stesso core quando si chiama QueryPerformanceCounter.

Caratteristiche dell'orologio hardware di basso livello

Queste sezioni mostrano caratteristiche dell'orologio hardware di basso livello.

Orologi assoluti e orologi di differenza

Gli orologi assoluti forniscono letture accurate dell'ora del giorno. In genere si basano sull'ora UTC (Coordinated Universal Time) e di conseguenza la loro accuratezza dipende in parte dalla modalità di sincronizzazione con un riferimento all'ora esterna. Gli orologi delle differenze misurano gli intervalli di tempo e in genere non si basano su un periodo di tempo esterno. QPC è un orologio di differenza e non è sincronizzato con un periodo di tempo esterno o riferimento. Quando si usa QPC per le misurazioni dell'intervallo di tempo, in genere si ottiene un'accuratezza migliore rispetto a quella ottenuta usando i timestamp derivati da un orologio assoluto. Ciò è dovuto al fatto che il processo di sincronizzazione del tempo di un orologio assoluto può introdurre turni di fase e frequenza che aumentano l'incertezza delle misurazioni a breve intervallo di tempo.

Risoluzione, precisione, accuratezza e stabilità

QPC usa un contatore hardware come base. I timer hardware sono costituiti da tre parti: un generatore di tick, un contatore che conta i tick e un mezzo per recuperare il valore del contatore. Le caratteristiche di questi tre componenti determinano la risoluzione, la precisione, l'accuratezza e la stabilità del QPC.

Se un generatore hardware fornisce tick a una frequenza costante, gli intervalli di tempo possono essere misurati semplicemente contando questi tick. La frequenza con cui vengono generati i tick viene chiamata frequenza ed espressa inHz (Hz). Il reciproco della frequenza viene chiamato intervallo di tempo o intervallo di graduazione ed è espresso in un'unità temporale di sistema internazionale (SI) appropriata (ad esempio, secondo, millisecondo, microsecondo o nanosecondo).

intervallo di tempo

La risoluzione del timer è uguale al periodo. La risoluzione determina la possibilità di distinguere tra due timestamp e posiziona un limite inferiore sugli intervalli di tempo più piccoli che possono essere misurati. Questo è talvolta chiamato risoluzione di graduazione.

La misurazione digitale del tempo introduce un'incertezza delle misurazioni di ± 1 tick perché il contatore digitale avanza in passaggi discreti, mentre il tempo avanza continuamente. Questa incertezza è detta errore di quantizzazione. Per le misurazioni tipiche degli intervalli di tempo, questo effetto può essere spesso ignorato perché l'errore di quantizzazione è molto più piccolo dell'intervallo di tempo misurato.

misurazione del tempo digitale

Tuttavia, se il periodo misurato è piccolo e si avvicina alla risoluzione del timer, sarà necessario prendere in considerazione questo errore di quantizzazione. La dimensione dell'errore introdotto è quella di un periodo di clock.

I due diagrammi seguenti illustrano l'impatto della ± 1 incertezza di graduazione usando un timer con una risoluzione di 1 unità temporale.

incertezza di graduazione

QueryPerformanceFrequency restituisce la frequenza del QPC e il periodo e la risoluzione sono uguali al reciproco di questo valore. La frequenza del contatore delle prestazioni restituita da QueryPerformanceFrequency viene determinata durante l'inizializzazione del sistema e non cambia durante l'esecuzione del sistema.

Nota

Spesso QueryPerformanceFrequency non restituisce la frequenza effettiva del generatore di tick hardware. Ad esempio, in alcune versioni precedenti di Windows, QueryPerformanceFrequency restituisce la frequenza TSC divisa da 1024; e quando viene eseguito in un hypervisor che implementa l'interfaccia hypervisor versione 1.0 (o sempre in alcune versioni più recenti di Windows), la frequenza del contatore delle prestazioni è fissa a 10 MHz. Di conseguenza, non si presuppone che QueryPerformanceFrequency restituirà un valore derivato dalla frequenza hardware.

 

QueryPerformanceCounter legge il contatore delle prestazioni e restituisce il numero totale di tick che si sono verificati dopo l'avvio del sistema operativo Windows, incluso il momento in cui il computer era in stato di sospensione, ad esempio standby, ibernazione o standby connesso.

Questi esempi illustrano come calcolare l'intervallo di tick e la risoluzione e come convertire il conteggio dei tick in un valore di tempo.

Esempio 1

QueryPerformanceFrequency restituisce il valore 3.125.000 in un determinato computer. Qual è l'intervallo di graduazione e la risoluzione delle misurazioni QPC in questo computer? L'intervallo di graduazione, o il periodo, è il reciproco di 3.125.0000, ovvero 0,00000320 (320 nanosecondi). Pertanto, ogni segno di spunta rappresenta il passaggio di 320 nanosecondi. Gli intervalli di tempo inferiori a 320 nanosecondi non possono essere misurati in questa macchina.

Intervallo di graduazione = 1/(Frequenza prestazioni)

Intervallo di spunta = 1/3.125.000 = 320 ns

Esempio 2

Nella stessa macchina dell'esempio precedente, la differenza dei valori restituiti da due chiamate successive a QPC è 5. Quanto tempo è trascorso tra le due chiamate? 5 zecche moltiplicate per 320 nanosecondi restituisce 1,6 microsecondi.

ElapsedTime = Ticks * Intervallo di graduazione

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

Richiede tempo per accedere (lettura) al contatore dei tick dal software e questo tempo di accesso può ridurre la precisione della misurazione del tempo. Questo perché l'intervallo minimo (intervallo di tempo più piccolo che può essere misurato) è maggiore della risoluzione e del tempo di accesso.

Precisione = MAX [ Risoluzione, AccessTime]

Si consideri ad esempio un timer hardware ipotetico con una risoluzione di 100 nanosecondi e un tempo di accesso a 800 nanosecondi. Questo potrebbe essere il caso se il timer della piattaforma è stato usato anziché il registro TSC come base di QPC. Pertanto, la precisione sarebbe 800 nanosecondi non 100 nanosecondi, come illustrato in questo calcolo.

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

Queste due figure illustrano questo effetto.

Tempo di accesso qpc

Se il tempo di accesso è maggiore della risoluzione, non provare a migliorare la precisione indovinando. In altre parole, si tratta di un errore per presupporre che il timestamp venga preso esattamente al centro o all'inizio o alla fine della chiamata.

Si consideri al contrario l'esempio seguente in cui il tempo di accesso QPC è di soli 20 nanosecondi e la risoluzione dell'orologio hardware è di 100 nanosecondi. Questo potrebbe essere il caso se il registro TSC è stato usato come base per QPC. Qui la precisione è limitata dalla risoluzione dell'orologio.

precisione qpc

In pratica, è possibile trovare origini temporali per cui il tempo necessario per leggere il contatore è maggiore o minore della risoluzione. In entrambi i casi, la precisione sarà maggiore dei due.

Questa tabella fornisce informazioni sulla risoluzione approssimativa, sull'ora di accesso e sulla precisione di un'ampia gamma di orologi. Si noti che alcuni dei valori variano con processori diversi, piattaforme hardware e velocità del processore.

Origine orologio Frequenza di clock nominale Risoluzione dell'orologio Tempo di accesso (tipico) Precisione
PC RTC 64 Hz 15,625 millisecondi N/D N/D
Contatore delle prestazioni delle query usando TSC con un orologio del processore a 3 GHz 3 MHz 333 nanosecondi 30 nanosecondi 333 nanosecondi
Istruzione del computer RDTSC in un sistema con un tempo di ciclo 3 GHz 3 GHz 333 picosecondi 30 nanosecondi 30 nanosecondi

 

Poiché QPC usa un contatore hardware, quando si comprendono alcune caratteristiche di base dei contatori hardware, si ottengono informazioni sulle funzionalità e le limitazioni di QPC.

Il generatore di tick hardware più comunemente usato è un oscillatore di cristallo. Il cristallo è un piccolo pezzo di quarzo o altro materiale ceramico che presenta caratteristiche piezoelettriche che forniscono un riferimento a frequenza poco costoso con eccellente stabilità e accuratezza. Questa frequenza viene usata per generare i tick conteggiati dall'orologio.

L'accuratezza di un timer fa riferimento al grado di conformità a un valore true o standard. Ciò dipende principalmente dalla capacità dell'oscillatore di cristallo di fornire tick alla frequenza specificata. Se la frequenza di oscillazione è troppo elevata, l'orologio "eseguirà veloce" e gli intervalli misurati appariranno più lunghi di quanto siano realmente; e se la frequenza è troppo bassa, l'orologio 'eseguirà lento', e gli intervalli misurati verranno visualizzati più brevi di quanto siano realmente.

Per le misurazioni tipiche degli intervalli di tempo per una breve durata (ad esempio, misurazioni del tempo di risposta, misurazioni della latenza di rete e così via), l'accuratezza dell'oscillatore hardware è in genere sufficiente. Tuttavia, per alcune misurazioni l'accuratezza della frequenza dell'oscillatore diventa importante, in particolare per intervalli di tempo lunghi o quando si desidera confrontare le misurazioni eseguite su macchine diverse. La parte restante di questa sezione illustra gli effetti dell'accuratezza dell'oscillatore.

La frequenza di oscillazione dei cristalli viene impostata durante il processo di produzione e viene specificata dal produttore in termini di frequenza specificata più o meno una tolleranza di produzione espressa in "parti per milione" (ppm), denominata offset di frequenza massima. Un cristallo con una frequenza specificata di 1.000.000 Hz e un offset massimo di frequenza di ± 10 ppm sarebbe entro limiti di specifica se la sua frequenza effettiva era compresa tra 999.990 Hz e 1.000.010 Hz.

Sostituendo le parti della frase al milione con microsecondi al secondo, è possibile applicare questo errore di offset di frequenza alle misurazioni degli intervalli di tempo. Un oscillatore con un offset + 10 ppm avrebbe un errore di 10 microsecondi al secondo. Di conseguenza, quando si misura un intervallo di 1 secondo, si eseguirà rapidamente e si misura un intervallo di 1 secondo come 0,999990 secondi.

Un riferimento pratico è che un errore di frequenza di 100 ppm causa un errore di 8,64 secondi dopo 24 ore. Questa tabella presenta l'incertezza della misurazione a causa dell'errore accumulato per intervalli di tempo più lunghi.

Durata intervallo di tempo Incertezza di misurazione dovuta all'errore accumulato con tolleranza di frequenza +/- 10 PPM
1 microsecondo ± 10 picosecondi (10-12)
1 millisecondo ± 10 nanosecondi (10-9)
1 secondo ± 10 microsecondi
1 ora ± 60 microsecondi
1 giorno ± 0,86 secondi
1 settimana ± 6,08 secondi

 

La tabella precedente mostra che per piccoli intervalli di tempo l'errore di offset della frequenza può essere spesso ignorato. Tuttavia, per intervalli di tempo lunghi, anche un piccolo offset di frequenza può comportare un'incertezza significativa della misurazione.

Gli oscillatori di cristallo usati nei computer personali e nei server vengono in genere prodotti con una tolleranza di frequenza di ± da 30 a 50 parti al milione e raramente, i cristalli possono essere disattivati da fino a 500 ppm. Anche se i cristalli con tolleranze di offset di frequenza molto più strette sono disponibili, sono più costosi e quindi non vengono usati nella maggior parte dei computer.

Per ridurre gli effetti negativi di questo errore di offset di frequenza, le versioni recenti di Windows, in particolare Windows 8, usano più timer hardware per rilevare l'offset di frequenza e compensarlo per quanto possibile. Questo processo di calibrazione viene eseguito all'avvio di Windows.

Come illustrato negli esempi seguenti, l'errore di offset di frequenza di un orologio hardware influisce sull'accuratezza raggiungibile e la risoluzione dell'orologio può essere meno importante.

l'errore di offset della frequenza influisce sulla precisione raggiungibile

Esempio 1

Si supponga di eseguire misurazioni a intervalli di tempo usando un oscillatore a 1 MHz, che ha una risoluzione di 1 microsecondo e un errore di offset di frequenza massimo di ±50 ppm. Ora, si supponga che l'offset sia esattamente +50 ppm. Ciò significa che la frequenza effettiva sarebbe 1.000.050 Hz. Se è stato misurato un intervallo di tempo di 24 ore, la misurazione sarà troppo breve (23:59:55,700000 misurata rispetto alle 24:00:00:00.00000 effettive).

Secondi in un giorno = 86400

Errore di offset di frequenza = 50 ppm = 0,00005

86.400 secondi * 0,00005 = 4,3 secondi

Esempio 2

Si supponga che l'orologio TSC del processore sia controllato da un oscillatore di cristallo e abbia una frequenza specificata di 3 GHz. Ciò significa che la risoluzione sarebbe 1/3.000.000.000.000 o circa 333 picosecondi. Si supponga che il cristallo usato per controllare l'orologio del processore abbia una tolleranza di frequenza di ±50 ppm ed è effettivamente +50 ppm. Nonostante la risoluzione impressionante, la misurazione dell'intervallo di tempo di 24 ore sarà ancora troppo breve. (23:59:55.700000000000 misurata rispetto a 24:00:00.00000000000 effettivo).

Secondi in un giorno = 86400

Errore di offset di frequenza = 50 ppm = 0,00005

86.400 secondi * 0,00005 = 4,3 secondi

Ciò mostra che un orologio TSC ad alta risoluzione non fornisce necessariamente misurazioni più accurate rispetto a un orologio di risoluzione inferiore.

Esempio 3

Prendere in considerazione l'uso di due computer diversi per misurare lo stesso intervallo di tempo di 24 ore. Entrambi i computer hanno un oscillatore con un offset massimo di frequenza di ± 50 ppm. Quanto lontano può essere la misurazione dello stesso intervallo di tempo su questi due sistemi? Come negli esempi precedenti, ± 50 ppm restituisce un errore massimo di ± 4,3 secondi dopo 24 ore. Se un sistema esegue 4,3 secondi velocemente e l'altro 4,3 secondi rallenta, l'errore massimo dopo 24 ore potrebbe essere di 8,6 secondi.

Secondi in un giorno = 86400

Errore di offset di frequenza = ±50 ppm = ±0.00005

±(86,400 secondi * 0,00005) = ±4,3 secondi

Offset massimo tra i due sistemi = 8,6 secondi

In riepilogo, l'errore di offset della frequenza diventa sempre più importante quando si misurano intervalli di tempo lunghi e quando si confrontano le misurazioni tra sistemi diversi.

La stabilità di un timer descrive se la frequenza di graduazione cambia nel tempo, ad esempio come risultato delle variazioni delle temperature. I cristalli di quarzo usati come generatori di zecche nei computer mostreranno piccole variazioni nella frequenza come funzione della temperatura. L'errore causato dalla deriva termica è in genere piccolo rispetto all'errore di offset di frequenza per intervalli di temperatura comuni. Tuttavia, i progettisti di software per apparecchiature portatili o attrezzature soggetti a grandi fluttuazioni di temperatura potrebbero dover considerare questo effetto.

Informazioni sul timer hardware

Registro TSC (x86 e x64)

Tutti i processori Intel e AMD moderni contengono un registro TSC che è un registro a 64 bit che aumenta a una frequenza elevata, in genere uguale al clock del processore. Il valore di questo contatore può essere letto tramite le istruzioni del computer RDTSC o RDTSCP , fornendo tempi di accesso e costi di calcolo molto bassi nell'ordine di decine o centinaia di cicli di computer, a seconda del processore.

Anche se il registro TSC sembra un meccanismo di timestamp ideale, ecco le circostanze in cui non può funzionare in modo affidabile per scopi di conservazione temporale:

  • Non tutti i processori hanno registri TSC utilizzabili, quindi l'uso del registro TSC nel software crea direttamente un problema di portabilità. In questo caso, Windows seleziona un'origine temporale alternativa per QPC , che evita il problema di portabilità.
  • Alcuni processori possono variare la frequenza dell'orologio TSC o arrestare l'avanzamento del registro TSC, che rende il TSC non adatto a scopi di intervallo per questi processori. Questi processori hanno registri TSC non invarianti. Windows rileverà automaticamente questo e seleziona un'origine temporale alternativa per QPC.
  • Anche se un host di virtualizzazione ha un TSC utilizzabile, la migrazione in tempo reale delle macchine virtuali in esecuzione quando l'host di virtualizzazione di destinazione non dispone o usa il ridimensionamento TSC assistito dall'hardware può causare una modifica della frequenza TSC visibile agli ospiti. Si prevede che se questo tipo di migrazione in tempo reale è possibile per un guest, che l'hypervisor cancella il bit di funzionalità TSC invariante in CPUID.
  • Nei sistemi multi-processori o multi-core, alcuni processori e sistemi non possono sincronizzare gli orologi in ogni core allo stesso valore. Windows rileverà automaticamente questo e seleziona un'origine temporale alternativa per QPC.
  • In alcuni sistemi multiprocessore di grandi dimensioni, potrebbe non essere possibile sincronizzare i clock del processore allo stesso valore anche se il processore ha un TSC invariante. Windows rileverà automaticamente questo e seleziona un'origine temporale alternativa per QPC.
  • Alcuni processori eseguiranno istruzioni non ordinate. Ciò può comportare conteggi di cicli non corretti quando RDTSC viene usato per eseguire sequenze di istruzioni in quanto l'istruzione RDTSC potrebbe essere eseguita in un momento diverso rispetto a quello specificato nel programma. L'istruzione RDTSCP è stata introdotta in alcuni processori in risposta a questo problema.

Come altri timer, il TSC si basa su un oscillatore di cristallo la cui frequenza esatta non è nota in anticipo e che ha un errore di offset di frequenza. Pertanto, prima di poterlo usare, deve essere calibrato usando un altro riferimento di intervallo.

Durante l'inizializzazione del sistema, Windows verifica se il TSC è adatto per scopi di intervallo ed esegue la calibrazione e la sincronizzazione core di frequenza necessarie.

Orologio PM (x86 e x64)

Il timer ACPI, noto anche come orologio PM, è stato aggiunto all'architettura di sistema per fornire timestamp affidabili indipendentemente dalla velocità dei processori. Poiché questo era l'unico obiettivo di questo timer, fornisce un timestamp in un singolo ciclo di orologio, ma non fornisce altre funzionalità.

Timer HPET (x86 e x64)

Il timer di eventi ad alta precisione (HPET) è stato sviluppato congiuntamente da Intel e Microsoft per soddisfare i requisiti di temporizzazione di multimediali e altre applicazioni sensibili al tempo. A differenza del TSC, che è una risorsa per processore, HPET è una risorsa a livello di piattaforma condivisa, anche se un sistema può avere più HPETs. Il supporto HPET è stato in Windows da Windows Vista e Windows 7 e Windows 8 certificazione Logo hardware richiede il supporto HPET nella piattaforma hardware.

Contatore del sistema timer generico (arm)

Le piattaforme basate su Arm non dispongono di un orologio TSC, HPET o PM perché è disponibile su piattaforme basate su Intel o AMD. I processori arm forniscono invece il timer generico (talvolta denominato Timer intervallo generico o GIT) che contiene un registro contatore di sistema (ad esempio, CNTVCT_EL0). Il contatore del sistema timer generico è un'origine temporale a livello di piattaforma a frequenza fissa. Inizia a zero all'avvio e aumenta a una velocità elevata. In Armv8.6 o versione successiva, questo è definito esattamente come 1 GHz, ma deve essere determinato leggendo il registro della frequenza di orologio impostato dal firmware di avvio iniziale. Per altre informazioni, vedere il capitolo "The Generic Timer in AArch64 state" in "Arm Architecture Reference Manual for A-profile architecture" (DDI 0487).

Contatore ciclo (arm)

Le piattaforme basate su Arm forniscono un registro del contatore cicli di monitoraggi delle prestazioni, ad esempio PMCCNTR_EL0. Questo contatore conta cicli di clock del processore. Non è invariante e le sue unità potrebbero non essere correlate in tempo reale. Non è consigliabile usare questo registro per ottenere timestamp.