Acquisition d’horodatages haute résolution
Windows fournit des API que vous pouvez utiliser pour acquérir des horodatages haute résolution ou mesurer des intervalles de temps. L’API principale pour le code natif est QueryPerformanceCounter (QPC). Pour les pilotes de périphérique, l’API en mode noyau est KeQueryPerformanceCounter. Pour le code managé, la classe System.Diagnostics.Stopwatch utilise QPC comme base de temps précise.
QPC est indépendant de toute référence d’heure externe et n’est pas synchronisé avec. Pour récupérer des horodatages qui peuvent être synchronisés avec une référence d’heure externe, comme le temps universel coordonné (UTC) à utiliser dans les mesures d’heure de la journée à haute résolution, utilisez GetSystemTimePreciseAsFileTime.
Les horodatages et les mesures d’intervalle de temps font partie intégrante des mesures des performances de l’ordinateur et du réseau. Ces opérations de mesure des performances incluent le calcul du temps de réponse, du débit et de la latence, ainsi que l’exécution du code de profilage. Chacune de ces opérations implique une mesure des activités qui se produisent pendant un intervalle de temps défini par un événement de début et de fin qui peut être indépendant de toute référence d’heure de la journée externe.
QPC est généralement la meilleure méthode à utiliser pour horodatage des événements et mesurer les petits intervalles de temps qui se produisent sur le même système ou la même machine virtuelle. Envisagez d’utiliser GetSystemTimePreciseAsFileTime lorsque vous souhaitez horodater des événements sur plusieurs machines, à condition que chaque machine participe à un schéma de synchronisation de temps tel que le protocole NTP (Network Time Protocol). QPC vous aide à éviter les difficultés qui peuvent être rencontrées avec d’autres approches de mesure du temps, telles que la lecture directe du compteur d’horodatage (TSC) du processeur.
- Prise en charge de QPC dans les versions de Windows
- Conseils pour l’acquisition d’horodatages
- FAQ général sur QPC et TSC
- FAQ sur la programmation avec QPC et TSC
- Caractéristiques de l’horloge matérielle de bas niveau
- Informations sur le minuteur matériel
Prise en charge de QPC dans les versions de Windows
QPC a été introduit dans Windows 2000 et Windows XP et a évolué pour tirer parti des améliorations apportées à la plateforme matérielle et aux processeurs. Ici, nous décrivons les caractéristiques de QPC sur différentes versions de Windows pour vous aider à gérer les logiciels qui s’exécutent sur ces versions de Windows.
Windows XP et Windows 2000
QPC est disponible sur Windows XP et Windows 2000 et fonctionne bien sur la plupart des systèmes. Toutefois, le BIOS de certains systèmes matériels n’a pas indiqué correctement les caractéristiques du processeur matériel (un TSC non invariant), et certains systèmes multicœurs ou multiprocesseurs utilisaient des processeurs avec des TSC qui ne pouvaient pas être synchronisés entre les cœurs. Les systèmes avec un microprogramme défectueux qui exécutent ces versions de Windows peuvent ne pas fournir la même lecture QPC sur différents cœurs s’ils utilisent le TSC comme base pour QPC.
Windows Vista et Windows Server 2008
Tous les ordinateurs fournis avec Windows Vista et Windows Server 2008 ont utilisé un compteur de plateforme (HPET )) ou le minuteur de gestion de l’alimentation ACPI (PM timer) comme base pour QPC. Ces minuteurs de plateforme ont une latence d’accès plus élevée que le TSC et sont partagés entre plusieurs processeurs. Cela limite la scalabilité de QPC si elle est appelée simultanément à partir de plusieurs processeurs.
Windows 7 et Windows Server 2008 R2
La majorité des ordinateurs Windows 7 et Windows Server 2008 R2 ont des processeurs avec des TSC à débit constant et utilisent ces compteurs comme base pour QPC. Les TSC sont des compteurs matériels haute résolution par processeur qui sont accessibles avec une latence et une surcharge très faibles (de l’ordre de 10 ou 100 cycles de machine, selon le type de processeur). Windows 7 et Windows Server 2008 R2 utilisent des TSC comme base de QPC sur des systèmes de domaine à horloge unique où le système d’exploitation (ou l’hyperviseur) est en mesure de synchroniser étroitement les TSC individuels sur tous les processeurs lors de l’initialisation du système. Sur ces systèmes, le coût de lecture du compteur de performances est considérablement inférieur par rapport aux systèmes qui utilisent un compteur de plateforme. En outre, il n’y a pas de surcharge supplémentaire pour les appels simultanés et les requêtes en mode utilisateur ignorent souvent les appels système, ce qui réduit davantage la surcharge. Sur les systèmes où le TSC ne convient pas pour le chronométrage, Windows sélectionne automatiquement un compteur de plateforme (le minuteur HPET ou le minuteur PM ACPI) comme base pour QPC.
Windows 8, Windows 8.1, Windows Server 2012 et Windows Server 2012 R2
Windows 8, Windows 8.1, Windows Server 2012 et Windows Server 2012 R2 utilisent des TSC comme base pour le compteur de performances. L’algorithme de synchronisation TSC a été considérablement amélioré pour mieux prendre en charge les systèmes volumineux avec de nombreux processeurs. En outre, la prise en charge de la nouvelle API d’heure précise a été ajoutée, ce qui permet d’acquérir des horodatages précis à partir du système d’exploitation. Pour plus d’informations, consultez GetSystemTimePreciseAsFileTime. Sur les appareils Windows RT et Windows 11 et Windows 10 utilisant des processeurs Arm, le compteur de performances est basé sur un compteur de plateforme propriétaire ou sur le compteur système fourni par le minuteur générique Arm si la plateforme est ainsi équipée.
Conseils pour l’acquisition d’horodatages
Windows a et continuera d’investir dans la fourniture d’un compteur de performances fiable et efficace. Lorsque vous avez besoin d’horodatages avec une résolution de 1 microseconde ou plus et que vous n’avez pas besoin que les horodatages soient synchronisés avec une référence d’heure externe, choisissez QueryPerformanceCounter, KeQueryPerformanceCounter ou KeQueryInterruptTimePrecise. Lorsque vous avez besoin d’horodatages synchronisés UTC avec une résolution de 1 microseconde ou supérieure, choisissez GetSystemTimePreciseAsFileTime ou KeQuerySystemTimePrecise.
Sur un nombre relativement faible de plateformes qui ne peuvent pas utiliser le registre TSC comme base QPC , par exemple, pour des raisons expliquées dans Informations du minuteur matériel, l’acquisition d’horodatages haute résolution peut être beaucoup plus coûteuse que l’acquisition d’horodatages avec une résolution inférieure. Si la résolution de 10 à 16 millisecondes est suffisante, vous pouvez utiliser GetTickCount64, QueryInterruptTime, QueryUnbiasedInterruptTime, KeQueryInterruptTime ou KeQueryUnbiasedInterruptTime pour obtenir des horodatages qui ne sont pas synchronisés avec une référence d’heure externe. Pour les horodatages synchronisés UTC, utilisez GetSystemTimeAsFileTime ou KeQuerySystemTime. Si une résolution plus élevée est nécessaire, vous pouvez utiliser QueryInterruptTimePrecise, QueryUnbiasedInterruptTimePrecise ou KeQueryInterruptTimePrecise pour obtenir des horodatages.
En général, les résultats des compteurs de performances sont cohérents entre tous les processeurs dans les systèmes multicœurs et multiprocesseurs, même lorsqu’ils sont mesurés sur différents threads ou processus. Voici quelques exceptions à cette règle :
Les systèmes d’exploitation antérieurs à Windows Vista qui s’exécutent sur certains processeurs peuvent violer cette cohérence pour l’une des raisons suivantes :
- Les processeurs matériels ont un TSC non invariant et le BIOS n’indique pas correctement cette condition.
- L’algorithme de synchronisation TSC utilisé n’était pas adapté aux systèmes avec un grand nombre de processeurs.
Lorsque vous comparez les résultats des compteurs de performances acquis à partir de différents threads, tenez compte des valeurs qui diffèrent par ± 1 coche pour avoir un ordre ambigu. Si les horodatages sont extraits du même thread, cette incertitude ± 1 tick ne s’applique pas. Dans ce contexte, le terme tick fait référence à une période de temps égale à 1 ÷ (la fréquence du compteur de performances obtenue à partir de QueryPerformanceFrequency).
Lorsque vous utilisez le compteur de performances sur de grands systèmes serveurs avec des domaines à plusieurs horloges qui ne sont pas synchronisés dans le matériel, Windows détermine que le TSC ne peut pas être utilisé à des fins de minutage et sélectionne un compteur de plateforme comme base pour QPC. Bien que ce scénario génère toujours des horodatages fiables, la latence et la scalabilité de l’accès sont affectées. Par conséquent, comme indiqué précédemment dans les instructions d’utilisation précédentes, utilisez uniquement les API qui fournissent une résolution de 1 microseconde ou une résolution supérieure lorsque cette résolution est nécessaire. Le TSC est utilisé comme base pour QPC sur les systèmes de domaine multi-horloge qui incluent la synchronisation matérielle de tous les domaines d’horloge du processeur, car cela les fait fonctionner comme un système de domaine d’horloge unique.
La fréquence du compteur de performances est fixe au démarrage du système et est cohérente entre tous les processeurs. Il vous suffit donc d’interroger la fréquence à partir de QueryPerformanceFrequency lors de l’initialisation de l’application, puis de mettre en cache le résultat.
Virtualisation
Le compteur de performances est censé fonctionner de manière fiable sur toutes les machines virtuelles invitées s’exécutant sur des hyperviseurs correctement implémentés. Toutefois, les hyperviseurs qui sont conformes à l’interface de l’hyperviseur version 1.0 et qui affichent l’éclairage du temps de référence peuvent offrir une surcharge sensiblement inférieure. Pour plus d’informations sur les interfaces et les illuminations d’hyperviseur, consultez Spécifications de l’hyperviseur.
Utilisation directe de TSC
Nous vous déconseillons vivement d’utiliser les instructions du processeur RDTSC ou RDTSCP pour interroger directement le TSC, car vous n’obtiendrez pas de résultats fiables sur certaines versions de Windows, sur les migrations actives de machines virtuelles et sur les systèmes matériels sans TSC invariant ou étroitement synchronisés. Au lieu de cela, nous vous encourageons à utiliser QPC pour tirer parti de l’abstraction, de la cohérence et de la portabilité qu’elle offre.
Exemples d’acquisition d’horodatages
Les différents exemples de code de ces sections montrent comment acquérir des horodatages.
Utilisation de QPC dans le code natif
Cet exemple montre comment utiliser QPC en code natif C et 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;
Acquisition d’horodatages haute résolution à partir de code managé
Cet exemple montre comment utiliser la classe System.Diagnostics.Stopwatch de code managé.
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 fournit également plusieurs méthodes pratiques pour effectuer des mesures d’intervalle de temps.
Utilisation de QPC en mode noyau
Le noyau Windows fournit un accès en mode noyau au compteur de performances via KeQueryPerformanceCounter à partir duquel le compteur de performances et la fréquence de performances peuvent être obtenus. KeQueryPerformanceCounter est disponible uniquement en mode noyau et est fourni pour les enregistreurs de pilotes de périphérique et d’autres composants en mode noyau.
Cet exemple montre comment utiliser KeQueryPerformanceCounter en mode noyau C et 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;
FAQ général sur QPC et TSC
Voici les réponses aux questions fréquemment posées sur QPC et les TSC en général.
-
QueryPerformanceCounter() est-il identique à la fonction Win32 GetTickCount() ou GetTickCount64() ?
-
Non. GetTickCount et GetTickCount64 ne sont pas liés à QPC. GetTickCount et GetTickCount64 retournent le nombre de millisecondes depuis le démarrage du système.
-
Dois-je utiliser QPC ou appeler directement les instructions RDTSC/RDTSCP ?
-
Pour éviter les problèmes d’erreur et de portabilité, nous vous encourageons vivement à utiliser QPC au lieu d’utiliser le registre TSC ou les instructions du processeur RDTSC ou RDTSCP .
-
Quelle est la relation entre QPC et une époque temporelle externe ? Peut-il être synchronisé avec une époque externe telle qu’UTC ?
-
QPC est basé sur un compteur matériel qui ne peut pas être synchronisé avec une référence d’heure externe, comme UTC. Pour obtenir des horodatages précis qui peuvent être synchronisés avec une référence UTC externe, utilisez GetSystemTimePreciseAsFileTime.
-
La QPC est-elle affectée par l’heure d’été, les secondes bissextiles, les fuseaux horaires ou les modifications d’heure système apportées par l’administrateur ?
-
Non. QPC est complètement indépendant de l’heure système et de l’heure UTC.
-
La précision QPC est-elle affectée par les changements de fréquence du processeur causés par la gestion de l’alimentation ou la technologie Turbo Boost ?
-
Non. Si le processeur a un TSC invariant, la QPC n’est pas affectée par ce type de modifications. Si le processeur n’a pas de TSC invariant, QPC revient à un minuteur matériel de plateforme qui ne sera pas affecté par les changements de fréquence du processeur ou la technologie Turbo Boost.
-
QPC fonctionne-t-il de manière fiable sur les systèmes multiprocesseurs, les systèmes multicœurs et les systèmes avec hyper-threading ?
-
Oui.
-
Comment faire déterminer et valider que QPC fonctionne sur mon ordinateur ?
-
Vous n’avez pas besoin d’effectuer de telles vérifications.
-
Quels processeurs ont des TSC non invariants ? Comment puis-je case activée si mon système a un TSC non invariant ?
-
Vous n’avez pas besoin d’effectuer cette case activée vous-même. Les systèmes d’exploitation Windows effectuent plusieurs vérifications lors de l’initialisation du système pour déterminer si le TSC est approprié comme base pour QPC. Toutefois, à des fins de référence, vous pouvez déterminer si votre processeur a un TSC invariant à l’aide de l’un des éléments suivants :
- utilitaire Coreinfo.exe de Windows Sysinternals
- vérification des valeurs retournées par l’instruction CPUID relative aux caractéristiques TSC
- documentation du fabricant du processeur
Voici les informations TSC-INVARIANT fournies par l’utilitaire de Coreinfo.exe Windows Sysinternals (www.sysinternals.com). Un astérisque signifie « 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 fonctionne-t-il de manière fiable sur Windows RT plateformes matérielles ?
-
Oui.
-
Quelle est la fréquence de substitution de QPC ?
-
Pas moins de 100 ans à compter du démarrage le plus récent du système, et potentiellement plus longtemps en fonction du minuteur matériel sous-jacent utilisé. Pour la plupart des applications, la substitution n’est pas un problème.
-
Quel est le coût de calcul de l’appel de QPC ?
-
Le coût des appels de calcul de QPC est déterminé principalement par la plateforme matérielle sous-jacente. Si le registre TSC est utilisé comme base pour QPC, le coût de calcul est déterminé principalement par le temps nécessaire au processeur pour traiter une instruction RDTSC . Ce temps va de 10 cycles d’UC à plusieurs centaines de cycles d’UC en fonction du processeur utilisé. Si le TSC ne peut pas être utilisé, le système sélectionne une autre base de temps matérielle. Étant donné que ces bases de temps sont situées sur la carte mère (par exemple, sur pci South Bridge ou PCH), le coût de calcul par appel est plus élevé que le TSC et se situe souvent entre 0,8 et 1,0 microsecondes en fonction de la vitesse du processeur et d’autres facteurs matériels. Ce coût est dominé par le temps nécessaire pour accéder au périphérique matériel sur la carte mère.
-
QPC nécessite-t-il une transition de noyau (appel système) ?
-
Une transition de noyau n’est pas nécessaire si le système peut utiliser le registre TSC comme base pour QPC. Si le système doit utiliser une autre base de temps, telle que le minuteur HPET ou PM, un appel système est nécessaire.
-
Le compteur de performances est-il monotonique (non décroissant) ?
-
Oui. QPC ne recule pas.
-
Le compteur de performances peut-il être utilisé pour classer les événements dans le temps ?
-
Oui. Toutefois, lors de la comparaison des résultats des compteurs de performances obtenus à partir de threads différents, les valeurs qui diffèrent par ± 1 graduation ont un ordre ambigu comme si elles avaient un horodatage identique.
-
Quelle est la précision du compteur de performances ?
-
La réponse dépend de divers facteurs. Pour plus d’informations, consultez Caractéristiques de l’horloge matérielle de bas niveau.
FAQ sur la programmation avec QPC et TSC
Voici les réponses aux questions fréquemment posées sur la programmation avec QPC et TSC.
-
Je dois convertir la sortie QPC en millisecondes. Comment éviter la perte de précision lors de la conversion en double ou en float ?
-
Il existe plusieurs points à garder à l’esprit lors de l’exécution de calculs sur des compteurs de performances entiers :
- La division entière perdra le reste. Cela peut entraîner une perte de précision dans certains cas.
- La conversion entre les entiers 64 bits et la virgule flottante (double) peut entraîner une perte de précision, car la mantisse à virgule flottante ne peut pas représenter toutes les valeurs intégrales possibles.
- La multiplication d’entiers 64 bits peut entraîner un dépassement de capacité d’entier.
En règle générale, retardez ces calculs et conversions aussi longtemps que possible pour éviter d’aggraver les erreurs introduites.
-
Comment puis-je convertir une QPC en cycles de 100 nanosecondes afin de pouvoir l’ajouter à un FICHIERTIME ?
-
Une heure de fichier est une valeur de 64 bits qui représente le nombre d’intervalles de 100 nanosecondes qui se sont écoulés depuis le 1er janvier 1601 (UTC) à 12 h 00. Les heures de fichier sont utilisées par les appels d’API Win32 qui retournent l’heure de la journée, comme GetSystemTimeAsFileTime et GetSystemTimePreciseAsFileTime. En revanche, QueryPerformanceCounter retourne des valeurs qui représentent le temps en unités de 1/(fréquence du compteur de performances obtenue à partir de QueryPerformanceFrequency). La conversion entre les deux nécessite le calcul du rapport entre l’intervalle QPC et les intervalles de 100 nanosecondes. Veillez à éviter de perdre la précision, car les valeurs peuvent être petites (0,0000001 / 0,000000340).
-
Pourquoi l’horodatage retourné par QPC est-il un entier signé ?
-
Les calculs qui impliquent des horodatages QPC peuvent impliquer une soustraction. En utilisant une valeur signée, vous pouvez gérer des calculs susceptibles de générer des valeurs négatives.
-
Comment puis-je obtenir des horodatages haute résolution à partir du code managé ?
-
Appelez la méthode Stopwatch.GetTimeStamp à partir de la classe System.Diagnostics.Stopwatch . Pour obtenir un exemple sur l’utilisation de Stopwatch.GetTimeStamp, consultez Acquisition d’horodatages haute résolution à partir de code managé.
-
Dans quelles circonstances QueryPerformanceFrequency retourne-t-il FALSE ou QueryPerformanceCounter retourne-t-il zéro ?
-
Cela ne se produit sur aucun système exécutant Windows XP ou version ultérieure.
-
Dois-je définir l’affinité de thread sur un cœur unique pour utiliser QPC ?
-
Non. Pour plus d’informations, consultez Conseils pour l’acquisition d’horodatages. Ce scénario n’est ni nécessaire ni souhaitable. L’exécution de ce scénario peut nuire aux performances de votre application en limitant le traitement à un cœur ou en créant un goulot d’étranglement sur un seul cœur si plusieurs threads définissent leur affinité sur le même cœur lors de l’appel de QueryPerformanceCounter.
Caractéristiques de l’horloge matérielle de bas niveau
Ces sections présentent les caractéristiques de l’horloge matérielle de bas niveau.
Horloges absolues et horloges de différence
Les horloges absolues fournissent des relevés précis de l’heure de la journée. Ils sont généralement basés sur le temps universel coordonné (UTC) et, par conséquent, leur précision dépend en partie de la façon dont ils sont synchronisés avec une référence d’heure externe. Les horloges de différence mesurent les intervalles de temps et ne sont généralement pas basées sur une époque de temps externe. QPC est une horloge de différence et n’est pas synchronisée avec une époque ou une référence temporelle externe. Lorsque vous utilisez QPC pour les mesures d’intervalle de temps, vous obtenez généralement une meilleure précision que celle que vous obtiendriez en utilisant des horodatages dérivés d’une horloge absolue. Cela est dû au fait que le processus de synchronisation de l’heure d’une horloge absolue peut introduire des décalages de phase et de fréquence qui augmentent l’incertitude des mesures d’intervalle de temps à court terme.
Résolution, précision, précision et stabilité
QPC utilise un compteur matériel comme base. Les minuteurs matériels se composent de trois parties : un générateur de graduations, un compteur qui compte les graduations et un moyen de récupérer la valeur du compteur. Les caractéristiques de ces trois composants déterminent la résolution, la précision, la précision et la stabilité de QPC.
Si un générateur matériel fournit des cycles à une fréquence constante, les intervalles de temps peuvent être mesurés simplement en comptant ces cycles. La vitesse à laquelle les graduations sont générées est appelée fréquence et exprimée en Hertz (Hz). La réciproque de la fréquence est appelée période ou intervalle de graduation et est exprimée dans une unité de temps du Système international d’unités (SI) appropriée (par exemple, seconde, milliseconde, microseconde ou nanoseconde).
La résolution du minuteur est égale à la période. La résolution détermine la possibilité de faire la distinction entre deux horodatages et place une limite inférieure sur les plus petits intervalles de temps pouvant être mesurés. C’est ce qu’on appelle parfois la résolution de graduation.
La mesure numérique du temps introduit une incertitude de mesure de ± 1 graduation, car le compteur numérique avance en étapes discrètes, tandis que le temps avance continuellement. Cette incertitude est appelée erreur de quantisation. Pour les mesures d’intervalle de temps classiques, cet effet peut souvent être ignoré, car l’erreur de quantisation est beaucoup plus petite que l’intervalle de temps mesuré.
Toutefois, si la période mesurée est petite et approche de la résolution du minuteur, vous devez prendre en compte cette erreur de quantisation. La taille de l’erreur introduite est celle d’une période d’horloge.
Les deux diagrammes suivants illustrent l’impact de l’incertitude ± 1 graduation à l’aide d’un minuteur avec une résolution de 1 unité de temps.
QueryPerformanceFrequency retourne la fréquence de QPC, et la période et la résolution sont égales à la réciproque de cette valeur. La fréquence du compteur de performances retournée par QueryPerformanceFrequency est déterminée pendant l’initialisation du système et ne change pas pendant l’exécution du système.
Notes
Souvent , QueryPerformanceFrequency ne retourne pas la fréquence réelle du générateur de tick matériel. Par exemple, dans certaines versions antérieures de Windows, QueryPerformanceFrequency retourne la fréquence TSC divisée par 1024 ; et lors de l’exécution sous un hyperviseur qui implémente l’interface de l’hyperviseur version 1.0 (ou toujours dans certaines versions plus récentes de Windows), la fréquence du compteur de performances est fixée à 10 MHz. Par conséquent, ne supposez pas que QueryPerformanceFrequency retourne une valeur dérivée de la fréquence matérielle.
QueryPerformanceCounter lit le compteur de performances et retourne le nombre total de graduations qui se sont produites depuis le démarrage du système d’exploitation Windows, y compris l’heure à laquelle l’ordinateur était en état de veille( veille, mise en veille prolongée ou veille connectée).
Ces exemples montrent comment calculer l’intervalle de graduation et la résolution, et comment convertir le nombre de graduations en valeur de temps.
-
Exemple 1
-
QueryPerformanceFrequency retourne la valeur 3 125 000 sur un ordinateur particulier. Quel est l’intervalle de graduation et la résolution des mesures QPC sur cette machine ? L’intervalle de graduation, ou période, est la réciproque de 3 125 000, soit 0,0000000320 (320 nanosecondes). Par conséquent, chaque coche représente le passage de 320 nanosecondes. Les intervalles de temps inférieurs à 320 nanosecondes ne peuvent pas être mesurés sur cette machine.
Tick Interval = 1/(Performance Frequency)
Tick Interval = 1/3 125 000 = 320 ns
-
Exemple 2
-
Sur la même machine que l’exemple précédent, la différence des valeurs retournées à partir de deux appels successifs à QPC est 5. Combien de temps s’est écoulé entre les deux appels ? 5 graduations multipliées par 320 nanosecondes donne 1,6 microsecondes.
IntervaldTime = Ticks * Tick Interval
Heure écoulée = 5 * 320 ns = 1,6 μs
Il faut du temps pour accéder (lire) le compteur de coche à partir du logiciel, et ce temps d’accès peut réduire la précision du de la mesure de temps. Cela est dû au fait que le temps d’intervalle minimal (le plus petit intervalle de temps pouvant être mesuré) est le plus grand de la résolution et du temps d’accès.
Précision = MAX [ Résolution, AccessTime]
Par exemple, considérez un minuteur matériel hypothétique avec une résolution de 100 nanosecondes et un temps d’accès de 800 nanosecondes. Cela peut être le cas si le minuteur de plateforme a été utilisé au lieu du registre TSC comme base de QPC. Ainsi, la précision serait de 800 nanosecondes et non de 100 nanosecondes comme indiqué dans ce calcul.
Précision = MAX [800 ns,100 ns] = 800 ns
Ces deux figures illustrent cet effet.
Si le temps d’accès est supérieur à la résolution, n’essayez pas d’améliorer la précision en devinant. En d’autres termes, il est erroné de supposer que l’horodatage est pris précisément au milieu, ou au début ou à la fin de l’appel.
En revanche, considérez l’exemple suivant dans lequel le temps d’accès QPC est de seulement 20 nanosecondes et la résolution de l’horloge matérielle est de 100 nanosecondes. Cela peut être le cas si le registre TSC a été utilisé comme base pour QPC. Ici, la précision est limitée par la résolution d’horloge.
Dans la pratique, vous pouvez trouver des sources de temps pour lesquelles le temps nécessaire pour lire le compteur est supérieur ou inférieur à la résolution. Dans les deux cas, la précision sera la plus grande des deux.
Ce tableau fournit des informations sur la résolution approximative, le temps d’accès et la précision de diverses horloges. Notez que certaines des valeurs varient selon les processeurs, les plateformes matérielles et les vitesses du processeur.
Source d’horloge | Fréquence d’horloge nominale | Résolution d’horloge | Temps d’accès (classique) | Precision |
---|---|---|---|---|
PC RTC | 64 Hz | 15,625 millisecondes | N/A | N/A |
Interroger le compteur de performances à l’aide de TSC avec une horloge processeur de 3 GHz | 3 MHz | 333 nanosecondes | 30 nanosecondes | 333 nanosecondes |
Instructions d’ordinateur RDTSC sur un système avec une durée de cycle de 3 GHz | 3 GHz | 333 picosecondes | 30 nanosecondes | 30 nanosecondes |
Étant donné que QPC utilise un compteur matériel, lorsque vous comprenez certaines caractéristiques de base des compteurs matériels, vous comprenez les fonctionnalités et les limitations de QPC.
Le générateur de tiques matériel le plus couramment utilisé est un oscillateur à cristaux. Le cristal est un petit morceau de quartz ou d’un autre matériau céramique qui présente des caractéristiques piézoélectriques qui fournissent une référence de fréquence peu coûteuse avec une excellente stabilité et précision. Cette fréquence est utilisée pour générer les tiques comptées par l’horloge.
La précision d’un minuteur fait référence au degré de conformité à une valeur true ou standard. Cela dépend principalement de la capacité de l’oscillateur à cristaux à fournir des tiques à la fréquence spécifiée. Si la fréquence d’oscillation est trop élevée, l’horloge « s’exécute rapidement », et les intervalles mesurés apparaissent plus longs qu’ils ne le sont réellement; et si la fréquence est trop faible, l’horloge s’exécutera lentement et les intervalles mesurés apparaîtront plus courts qu’ils ne le sont réellement.
Pour les mesures d’intervalle de temps typiques de courte durée (par exemple, les mesures de temps de réponse, les mesures de latence réseau, etc.), la précision de l’oscillateur matériel est généralement suffisante. Toutefois, pour certaines mesures, la précision de la fréquence de l’oscillateur devient importante, en particulier pour les intervalles de temps longs ou lorsque vous souhaitez comparer les mesures prises sur différentes machines. Le reste de cette section explore les effets de la précision de l’oscillateur.
La fréquence d’oscillation des cristaux est définie pendant le processus de fabrication et est spécifiée par le fabricant en fonction d’une fréquence spécifiée, plus ou moins, d’une tolérance de fabrication exprimée en « parties par million » (ppm), appelée décalage de fréquence maximal. Un cristal avec une fréquence spécifiée de 1 000 000 Hz et un décalage de fréquence maximal de ± 10 ppm se trouverait dans les limites de spécification si sa fréquence réelle était comprise entre 999 990 Hz et 1 000 010 Hz.
En remplaçant les parties d’expression par million par des microsecondes par seconde, nous pouvons appliquer cette erreur de décalage de fréquence aux mesures d’intervalle de temps. Un oscillateur avec un décalage de + 10 ppm aurait une erreur de 10 microsecondes par seconde. Par conséquent, lors de la mesure d’un intervalle de 1 seconde, il s’exécute rapidement et mesure un intervalle de 1 seconde comme 0,999990 seconde.
Une référence pratique est qu’une erreur de fréquence de 100 ppm provoque une erreur de 8,64 secondes après 24 heures. Ce tableau présente l’incertitude de mesure due à l’erreur accumulée pendant des intervalles de temps plus longs.
Durée de l’intervalle de temps | Incertitude de mesure due à l’erreur accumulée avec +/- tolérance de fréquence de 10 PPM |
---|---|
1 microseconde | ± 10 picosecondes (10-12) |
1 milliseconde | ± 10 nanosecondes (10-9) |
1 seconde | ± 10 microsecondes |
1 heure | ± 60 microsecondes |
1 jour | ± 0,86 seconde |
1 semaine | ± 6,08 secondes |
Le tableau précédent montre que pour de petits intervalles de temps, l’erreur de décalage de fréquence peut souvent être ignorée. Toutefois, pendant de longs intervalles de temps, même un léger décalage de fréquence peut entraîner une incertitude de mesure importante.
Les oscillateurs à cristaux utilisés dans les ordinateurs personnels et les serveurs sont généralement fabriqués avec une tolérance de fréquence de ± de 30 à 50 parties par million, et rarement, les cristaux peuvent être désactivés jusqu’à 500 ppm. Bien que des cristaux avec des tolérances de décalage de fréquence beaucoup plus strictes soient disponibles, ils sont plus coûteux et ne sont donc pas utilisés dans la plupart des ordinateurs.
Pour réduire les effets négatifs de cette erreur de décalage de fréquence, les versions récentes de Windows, en particulier Windows 8, utilisent plusieurs minuteurs matériels pour détecter le décalage de fréquence et le compenser dans la mesure du possible. Ce processus d’étalonnage est effectué lorsque Windows est démarré.
Comme le montrent les exemples suivants, l’erreur de décalage de fréquence d’une horloge matérielle influence la précision réalisable et la résolution de l’horloge peut être moins importante.
-
Exemple 1
-
Supposons que vous effectuez des mesures d’intervalle de temps à l’aide d’un oscillateur de 1 MHz, qui a une résolution de 1 microseconde et une erreur de décalage de fréquence maximale de ±50 ppm. Supposons maintenant que le décalage est exactement +50 ppm. Cela signifie que la fréquence réelle serait de 1 000 050 Hz. Si nous mesurons un intervalle de temps de 24 heures, notre mesure serait de 4,3 secondes trop courte (23:59:55,7000000 mesurés contre 24:00:00.000000 réel).
Secondes dans un jour = 86400
Erreur de décalage de fréquence = 50 ppm = 0,00005
86 400 secondes * 0,00005 = 4,3 secondes
-
Exemple 2
-
Supposons que l’horloge TSC du processeur soit contrôlée par un oscillateur à cristal et qu’elle ait une fréquence spécifiée de 3 GHz. Cela signifie que la résolution serait de 1/3 000 000 000 000 ou d’environ 333 picosecondes. Supposons que le cristal utilisé pour contrôler l’horloge du processeur a une tolérance de fréquence de ±50 ppm et est en fait de +50 ppm. Malgré la résolution impressionnante, une mesure d’intervalle de temps de 24 heures sera toujours 4,3 secondes trop courte. (23:59:55.700000000 mesuré contre 24:00:00.0000000000000 réels).
Secondes dans un jour = 86400
Erreur de décalage de fréquence = 50 ppm = 0,00005
86 400 secondes * 0,00005 = 4,3 secondes
Cela montre qu’une horloge TSC haute résolution ne fournit pas nécessairement des mesures plus précises qu’une horloge de résolution inférieure.
-
Exemple 3
-
Envisagez d’utiliser deux ordinateurs différents pour mesurer le même intervalle de temps de 24 heures. Les deux ordinateurs ont un oscillateur avec un décalage de fréquence maximal de ± 50 ppm. Quelle est la distance entre la mesure du même intervalle de temps sur ces deux systèmes ? Comme dans les exemples précédents, ± 50 ppm génère une erreur maximale de ± 4,3 secondes après 24 heures. Si un système s’exécute 4,3 secondes rapidement et que les autres 4,3 secondes sont lentes, l’erreur maximale après 24 heures peut être de 8,6 secondes.
Secondes dans un jour = 86400
Erreur de décalage de fréquence = ±50 ppm = ±0,00005
±(86 400 secondes * 0,00005) = ±4,3 secondes
Décalage maximal entre les deux systèmes = 8,6 secondes
En résumé, l’erreur de décalage de fréquence devient de plus en plus importante lors de la mesure de longs intervalles de temps et de la comparaison de mesures entre différents systèmes.
La stabilité d’un minuteur indique si la fréquence des graduations change au fil du temps, par exemple à la suite de changements de température. Les cristaux de quartz utilisés comme générateurs de tiques sur les ordinateurs présenteront de petits changements de fréquence en fonction de la température. L’erreur provoquée par la dérive thermique est généralement faible par rapport à l’erreur de décalage de fréquence pour les plages de température courantes. Toutefois, les concepteurs de logiciels pour l’équipement portable ou l’équipement soumis à de grandes fluctuations de température peuvent devoir tenir compte de cet effet.
Informations sur le minuteur matériel
-
TSC Register (x86 et x64)
-
Tous les processeurs Intel et AMD modernes contiennent un registre TSC qui est un registre 64 bits qui augmente à un rythme élevé, généralement égal à l’horloge du processeur. La valeur de ce compteur peut être lue dans les instructions de l’ordinateur RDTSC ou RDTSCP , ce qui fournit un temps d’accès très faible et un coût de calcul de l’ordre de dizaines ou de centaines de cycles de machine, selon le processeur.
Bien que le registre TSC semble être un mécanisme d’horodatage idéal, voici des circonstances dans lesquelles il ne peut pas fonctionner de manière fiable à des fins de chronométrage :
- Tous les processeurs ne disposent pas de registres TSC utilisables. Par conséquent, l’utilisation du registre TSC dans le logiciel crée directement un problème de portabilité. (Windows sélectionne une autre source de temps pour QPC dans ce cas, ce qui évite le problème de portabilité.)
- Certains processeurs peuvent faire varier la fréquence de l’horloge TSC ou arrêter l’avancement du registre TSC, ce qui rend le TSC inadapté à des fins de minutage sur ces processeurs. Ces processeurs ont des registres TSC non invariants. (Windows détecte automatiquement cela et sélectionne une autre source de temps pour QPC).
- Même si un hôte de virtualisation dispose d’un TSC utilisable, la migration dynamique des machines virtuelles en cours d’exécution lorsque l’hôte de virtualisation cible n’a pas ou n’utilise pas de mise à l’échelle TSC assistée par le matériel peut entraîner une modification de la fréquence TSC visible par les invités. (Si ce type de migration dynamique est possible pour un invité, l’hyperviseur efface le bit de fonctionnalité TSC invariant dans CPUID.)
- Sur les systèmes multiprocesseurs ou multicœurs, certains processeurs et systèmes ne peuvent pas synchroniser les horloges de chaque cœur à la même valeur. (Windows détecte automatiquement cela et sélectionne une autre source de temps pour QPC).
- Sur certains grands systèmes multiprocesseurs, il se peut que vous ne puissiez pas synchroniser les horloges du processeur avec la même valeur, même si le processeur a un TSC invariant. (Windows détecte automatiquement cela et sélectionne une autre source de temps pour QPC).
- Certains processeurs exécutent des instructions dans le désordre. Cela peut entraîner des nombres de cycles incorrects lorsque RDTSC est utilisé pour timer des séquences d’instructions, car l’instruction RDTSC peut être exécutée à un moment différent de celui spécifié dans votre programme. L’instruction RDTSCP a été introduite sur certains processeurs en réponse à ce problème.
Comme les autres minuteurs, le TSC est basé sur un oscillateur à cristaux dont la fréquence exacte n’est pas connue à l’avance et qui présente une erreur de décalage de fréquence. Ainsi, avant de pouvoir être utilisé, il doit être étalonné à l’aide d’une autre référence de minutage.
Lors de l’initialisation du système, Windows vérifie si le TSC convient à des fins de minutage et effectue l’étalonnage de fréquence et la synchronisation de cœurs nécessaires.
-
Horloge PM (x86 et x64)
-
Le minuteur ACPI, également appelé horloge PM, a été ajouté à l’architecture système pour fournir des horodatages fiables indépendamment de la vitesse des processeurs. Étant donné qu’il s’agissait de l’objectif unique de ce minuteur, il fournit un horodatage dans un seul cycle d’horloge, mais il ne fournit aucune autre fonctionnalité.
-
Minuteur HPET (x86 et x64)
-
Le minuteur d’événements de haute précision (HPET) a été développé conjointement par Intel et Microsoft pour répondre aux exigences de minutage des applications multimédia et d’autres applications sensibles au temps. Contrairement au TSC, qui est une ressource par processeur, le HPET est une ressource partagée à l’échelle de la plateforme, bien qu’un système puisse avoir plusieurs HPET. La prise en charge de HPET est dans Windows depuis Windows Vista, et la certification logo matériel Windows 7 et Windows 8 nécessite la prise en charge DE HPET dans la plateforme matérielle.
-
Compteur système du minuteur générique (Arm)
-
Les plateformes arm n’ont pas d’horloge TSC, HPET ou PM, comme il en existe sur les plateformes Intel ou AMD. Au lieu de cela, les processeurs Arm fournissent le minuteur générique (parfois appelé minuteur d’intervalle générique, ou GIT) qui contient un registre compteur système (par exemple, CNTVCT_EL0). Le compteur système du minuteur générique est une source de temps à fréquence fixe à l’échelle de la plateforme. Il commence à zéro au démarrage et augmente à un rythme élevé. Dans Armv8.6 ou version ultérieure, cette valeur est définie comme exactement 1 GHz, mais doit être déterminée en lisant le registre de fréquence d’horloge qui est défini par le microprogramme de démarrage précoce. Pour plus d’informations, consultez le chapitre « Le minuteur générique à l’état AArch64 » dans « Arm Architecture Reference Manual for A-profile architecture » (DDI 0487).
-
Compteur de cycles (arm)
-
Les plateformes basées sur arm fournissent un registre compteur de cycle de l’analyseur de performances (par exemple, PMCCNTR_EL0). Ce compteur compte les cycles d’horloge du processeur. Il n’est pas invariant et ses unités peuvent ne pas être corrélées en temps réel. Il n’est pas recommandé d’utiliser ce registre pour obtenir des horodatages.