Windows 7 fonctions de chronométrage - Comment utiliser GetSystemTimeAdjustment correctement?
J'ai couru quelques tests à l'aide de la GetSystemTimeAdjustment
fonctionner sur Windows 7, et a obtenu quelques résultats intéressants qui je ne peux pas expliquer. Le saf que je comprends, cette méthode doit retourner si l'heure du système est synchronisé périodiquement et, si elle l'est, à quel intervalle et avec qui incrément, il est mis à jour (voir GetSystemTimeAdjustment fonction sur MSDN).
De ce je suis que si j'ai une requête, le système de temps par exemple à l'aide de GetSystemTimeAsFileTime
repeatingly je devrais obtenir soit pas de changement (l'horloge système n'a pas été mis à jour), ou d'un changement qui est un multiple de l'intervalle récupérées par GetSystemTimeAdjustment
. Question: cette hypothèse Est correcte?
Considérons maintenant la suite de tests de code:
#include <windows.h>
#include <iostream>
#include <iomanip>
int main()
{
FILETIME fileStart;
GetSystemTimeAsFileTime(&fileStart);
ULARGE_INTEGER start;
start.HighPart = fileStart.dwHighDateTime;
start.LowPart = fileStart.dwLowDateTime;
for (int i=20; i>0; --i)
{
FILETIME timeStamp1;
ULARGE_INTEGER ts1;
GetSystemTimeAsFileTime(&timeStamp1);
ts1.HighPart = timeStamp1.dwHighDateTime;
ts1.LowPart = timeStamp1.dwLowDateTime;
std::cout << "Timestamp: " << std::setprecision(20) << (double)(ts1.QuadPart - start.QuadPart) / 10000000 << std::endl;
}
DWORD dwTimeAdjustment = 0, dwTimeIncrement = 0, dwClockTick;
BOOL fAdjustmentDisabled = TRUE;
GetSystemTimeAdjustment(&dwTimeAdjustment, &dwTimeIncrement, &fAdjustmentDisabled);
std::cout << "\nTime Adjustment disabled: " << fAdjustmentDisabled
<< "\nTime Adjustment: " << (double)dwTimeAdjustment/10000000
<< "\nTime Increment: " << (double)dwTimeIncrement/10000000 << std::endl;
}
Il faut 20 horodateurs dans une boucle et de les imprimer à la console. En fin de compte, il imprime l'incrémenter à laquelle l'horloge système est mis à jour. Je m'attends à voir les différences entre les horodateurs imprimé dans la boucle pour être 0 ou multiples de cette augmentation. Cependant, j'obtiens des résultats comme ceci:
Timestamp: 0
Timestamp: 0.0025000000000000001
Timestamp: 0.0074999999999999997
Timestamp: 0.01
Timestamp: 0.012500000000000001
Timestamp: 0.014999999999999999
Timestamp: 0.017500000000000002
Timestamp: 0.022499999999999999
Timestamp: 0.025000000000000001
Timestamp: 0.0275
Timestamp: 0.029999999999999999
Timestamp: 0.032500000000000001
Timestamp: 0.035000000000000003
Timestamp: 0.040000000000000001
Timestamp: 0.042500000000000003
Timestamp: 0.044999999999999998
Timestamp: 0.050000000000000003
Timestamp: 0.052499999999999998
Timestamp: 0.055
Timestamp: 0.057500000000000002
Time Adjustment disabled: 0
Time Adjustment: 0.0156001
Time Increment: 0.0156001
Il semble donc que l'heure du système est mis à jour avec un intervalle d'environ 0.0025 secondes et pas 0.0156 secondes que le retour par GetSystemTimeAdjustment
.
Question deux: Quelle est la raison?
OriginalL'auteur fdlm | 2011-10-07
Vous devez vous connecter pour publier un commentaire.
La
GetSystemTimeAsFileTime
API permet d'accéder à l'horloge murale en fichier format de l'heure.64 bits FILETIME structure reçoit le système de temps que FILETIME dans 100ns unités, qui ont été expiré depuis le 1er janvier 1601. L'appel à
GetSystemTimeAsFileTime
nécessite généralement de 10 ns 15 ns.Afin d'enquêter sur la véritable précision de l'heure du système fourni par cette API, la granularité qui vient avec les valeurs de temps doit être discuté. En d'autres termes: Quelle est la fréquence de l'heure du système mis à jour? Une première estimation est fournie par l'caché appel d'API:
NtQueryTimerResolution
est exporté par le natif de Windows NT bibliothèque NTDLL.DLL. Le ActualResolution signalés par cet appel représente la période de mise à jour de l'heure du système dans 100 ns unités, qui ne correspondent pas nécessairement à la période d'interruption. La valeur dépend de la plate-forme matérielle. Commune de plates-formes matérielles rapport 156,250 ou 100,144 pour ActualResolution; les plateformes de rapport d'un plus grand nombre; de nouveaux systèmes, particulièrement quand lesHPET
(High Precision Event Timer) ouconstant/invariant TSC
sont pris en charge, peut renvoyer 156,001 pour ActualResolution.C'est l'un des pulsations de contrôler le système. Le MinimumResolution et la ActualResolution sont pertinentes pour la configuration de la minuterie multimédia.
La ActualResolution peut être définie à l'aide de l'appel d'API
ou via la minuterie multimédia interface
avec la valeur de uPeriod dérivé de la plage autorisée par
qui remplit la structure
Les valeurs typiques sont de 1 ms pour wPeriodMin et 1 000 000 ms pour wPeriodMax.
Il est regrettable erreur d'interprétation lors de la recherche d'un les valeurs min/max ici:
NtQueryTimerResolution
d'autre part, stipule une résolution. La plus faible obtenue résolution (MinimumResolution) est dans la gamme jusqu'à environ 20 ms, tandis que la plus forte résolution (MaximumResolution) peut être de 0,5 ms. Cependant, l'0,5 ms resulution n'est pas accessible par le biais d'un detimeBeginPeriod
.La minuterie multimédia interface traite les périodes et NtQueryTimerResolution() gère les résolutions (réciproque de la valeur de la période).
Résumé:
GetSystemTimeAdjustment
n'est pas la fonction à regarder. Cette fonction indique si et comment les changements de temps sont fait. Selon le réglage de la minuterie multimédia interfacetimeBeginPeriod
, la progression du temps, peut être fait plus souvent et en plus petites portions. UtilisationNtQueryTimerResolution
pour recevoir le réel de l'incrément de temps. Et être conscient que le réglage de la minuterie multimédia de l'API a de l'influence sur les valeurs. (Exemple: Quand le lecteur multimédia est la présentation d'une vidéo, les temps sont courts.)Je diagnostiqué windows le temps compte, dans une large mesure. Certains résultats peuvent être trouvés ici.
Remarque: le Réglage de l'Heure: 0.0156001 identifie clairement windows VISTA ou supérieur avec
HPET
et/ouconstant/invariant TSC
sur votre système.Mise en œuvre: Si vous voulez prendre le temps de la transition:
Mais: Lorsque le filetime de transition est très court (par exemple définie par
timeBeginPeriod(wPeriodMin)
) toute sortie commefprintf
oustd::cout
pourrait détruire le résultat car il retarde la boucle. Dans de tels cas, je vous recommande de stocker les 20 résultats dans une structure de données et faire la sortie par la suite.Et: filetime de transition ne peut pas toujours être la même. Il se pourrait bien que le fichier incrément de temps ne correspond pas à la période de mise à jour. Voir le lien ci-dessus pour obtenir plus de détails et des exemples de ce comportement.
Edit: user de prudence lors de l'appel de timeBeginPeriod, comme des appels fréquents peuvent affecter de manière significative le système de l'horloge MSDN. Ce comportement s'applique à la version de Windows 7.
Appels à
timeBeginPeriod
/timeEndPeriod
ouNtSetTimerResolution
peut modifier l'heure du système de ActualResolution. Le faire très souvent des résultats considérables modifications de l'heure du système. Toutefois, lorsque les appels sont effectués à ou près de la transition de l'heure du système, les écarts sont beaucoup moins. L'interrogation d'un système de temps de transition/incrément avant d'appels à la fonction ci-dessus est conseillé pour les applications exigeantes comme le NTP. Synchronisation avec un serveur NTP est difficile quand indésirables des sauts dans le systemtime de progression se produit.Deuxième paramètre pour
NtQueryTimerResolution
doit êtreOUT PULONG MaximumResolution
, pasOUT LONGMaximumResolution
. Également ajouter des espaces entre les types de paramètre (PULONG) et les noms des paramètres.OriginalL'auteur Arno
Vous sont effectivement profilage combien de temps un passage dans la boucle for() prend. Je obtenir un peu plus de variabilité, mais 5 millisecondes est sujet de droit, à la sortie de la console n'est pas très rapide. Arbitrairement ajouter un peu plus de std::cout des déclarations pour le ralentir.
NtQueryTimerResolution (NTDLL.DLL) sera de retour l'horloge. GetSystemTimeAdjustment ne vous laisser savoir que vous soyez un système d'ajustement de l'heure est active et que la mise à jour des augmentations sont.
Eh bien, Pourquoi un fprintf si lent peut vous laisser sortir du blocage de la sortie. Je vous suggère de moins sortie à vraiment du sondage pour le fichier temps de transition.
GetSystemTimeAdjustment() retourne l'interruption de l'horloge par le biais de la 2ème argument. 156001 sur ma machine, comme prévu et documenté. Cela semble être controversé, donc j'ai juste supprimé.
il n'est pas surprenant que l'intervalle de temps intervalle est réglé à la même valeur que l'interruption de l'horloge de la période par défaut (ce qui signifie qu'un ajustement sera fait exactement une fois par tic d'horloge), mais d'après la documentation qu'ils ne sont pas synonymes.
OriginalL'auteur Hans Passant
GetSystemTimeAsFileTime la résolution dépend du système. S'il est vu, il a affirmé que son entre 10ms et 55ms. Les commentateurs sur la Document MSDN mettre à 15ms et "sous la milliseconde". Ce qu'il est en réalité semble pas clair, mais je n'ai jamais vu sa résolution revendiqué comme étant égale à 100 ns précision de l'horodatage.
Cela signifie qu'il y a toujours un écart et c'est aussi la raison pour laquelle les gens utilisent QueryPerformanceFrequency à la place.
GetSystemTimeAsFileTime()
est donnée par le TimeIncrement retourné parGetSystemTimeAdjustment()
. Ce ne doit pas être confondue avec la capacité du système de fichier du temps à représenter 100ns unités.J'ai mis à jour le lien vers l'ancienne docs. Merci pour cela. En aparté pourquoi croyez-vous il y a une relation entre
GetSystemTimeAsFileTime
etGetSystemTimeAdjustment
Système filetime représente 100 ns unités. Mais il n'a pas d'incrément de 100 ns étapes. Filetime mise à jour montant et la fréquence sont déterminées par un mécanisme complexe, qui prend soin sur l'ensemble de la gamme de matériel. Cela comprend l'interruption de la période et possible battement de fréquences, qui ne se produisent si l'interruption de la période ne correspond pas à la filetime quantique (TimeIncrement). Pour en savoir plus: Ma réponse ci-dessous et ceci.
OriginalL'auteur Conrad Frix