J'ai récemment décidé que je devais passer de l'utilisation des millisecondes aux microsecondes pour ma classe Timer, et après quelques recherches, j'ai décidé que QueryPerformanceCounter était probablement mon pari le plus sûr. (L'avertissement sur le fait Boost::Posix
que cela peut ne pas fonctionner sur l'API Win32 m'a un peu découragé). Cependant, je ne sais pas vraiment comment le mettre en œuvre.
Ce que je fais, c'est appeler la GetTicks()
fonction esque que j'utilise et l'attribuer à la startingTicks
variable de Timer . Ensuite, pour trouver le temps écoulé, je soustrais simplement la valeur de retour de la fonction de startingTicks
, et lorsque je réinitialise le minuteur, je rappelle simplement la fonction et lui attribue startTicks. Malheureusement, d'après le code que j'ai vu, ce n'est pas aussi simple que d'appeler QueryPerformanceCounter()
, et je ne suis pas sûr de ce que je suis censé passer comme argument.
Réponses:
Ce programme devrait afficher un nombre proche de 1000 (Windows Sleep n'est pas aussi précis, mais il devrait être comme 999).
La
StartCounter()
fonction enregistre le nombre de graduations du compteur de performance dans laCounterStart
variable. LaGetCounter()
fonction renvoie le nombre de millisecondes depuisStartCounter()
son dernier appel sous forme de double, donc siGetCounter()
renvoie 0,001, cela fait environ 1 microseconde depuisStartCounter()
son appel.Si vous voulez que la minuterie utilise les secondes à la place, changez
à
ou si vous voulez des microsecondes, utilisez
Mais c'est vraiment une question de commodité puisqu'elle renvoie un double.
la source
On a multiprocessor computer, it should not matter which processor is called. However, you can get different results on different processors due to bugs in the basic input/output system (BIOS) or the hardware abstraction layer (HAL).
Ce code n'est pas très imparfait, mais certains BIOS ou HAL.StartCounter
fonction:old_mask = SetThreadAffinityMask(GetCurrentThread,1);
puis le remettre à la finSetThreadAffinityMask ( GetCurrentThread , old_mask ) ;
. J'espère que cela fera l'affaire. Cela devrait empêcher mon thread d'être replanifié à autre chose que le premier cœur de processeur. (Ce qui n'est évidemment qu'une solution pour un environnement de test)J'utilise ces définitions:
Utilisation (parenthèses pour éviter les redéfinitions):
Sortie de l'exemple d'utilisation:
la source
En supposant que vous êtes sous Windows (si c'est le cas, vous devez marquer votre question comme telle!), Sur cette page MSDN vous pouvez trouver la source d'une
HRTimer
classe C ++ simple et utile qui encapsule les appels système nécessaires pour faire quelque chose de très proche de ce dont vous avez besoin (il serait facile d'y ajouter uneGetTicks()
méthode, en particulier, pour faire exactement ce dont vous avez besoin).Sur les plates-formes non Windows, il n'y a pas de fonction QueryPerformanceCounter, donc la solution ne sera pas directement portable. Cependant, si vous l'enveloppez dans une classe telle que celle mentionnée ci-dessus
HRTimer
, il sera plus facile de changer l'implémentation de la classe pour utiliser ce que la plate-forme actuelle est effectivement en mesure d'offrir (peut-être via Boost ou autre!).la source
Je voudrais étendre cette question avec un exemple de pilote NDIS sur l'obtention du temps. Comme on le sait, KeQuerySystemTime (imité sous NdisGetCurrentSystemTime) a une faible résolution au-dessus des millisecondes, et il existe certains processus comme les paquets réseau ou d'autres IRP qui peuvent avoir besoin d'un meilleur horodatage;
L'exemple est tout aussi simple:
où le diviseur est 10 ^ 3 ou 10 ^ 6 selon la résolution requise.
la source