101 votes

Comment utiliser QueryPerformanceCounter ?

Récemment, j'ai décidé que j'avais besoin de changer de l'aide de quelques millisecondes à quelques microsecondes pour ma classe Timer, et après quelques recherches, j'ai décidé que QueryPerformanceCounter est probablement mon plus sûr pari. (L'avertissement sur Boost::Posix qu'il peut ne pas fonctionne sur l'API Win32 de me mettre un peu). Cependant, je ne suis pas vraiment sûr de savoir comment la mettre en œuvre.

Ce que je fais est en appelant l' GetTicks() esque fonction que j'utilise et l'affectation du Timer startingTicks variable. Alors pour trouver la quantité de temps passé, j'ai juste soustraire la valeur renvoyée de la fonction de l' startingTicks, et quand je reset le timer je viens de l'appeler à nouveau la fonction et attribuer startingTicks. Malheureusement, à partir du code que j'ai vu il n'est pas aussi simple que d'appeler QueryPerformanceCounter(), et je ne suis pas sûr de ce que je suis censé passer en argument.

Toute aide est appréciée, merci.

167voto

Ramónster Points 1237
#include <windows.h>

double PCFreq = 0.0;
__int64 CounterStart = 0;

void StartCounter()
{
    LARGE_INTEGER li;
    if(!QueryPerformanceFrequency(&li))
	cout << "QueryPerformanceFrequency failed!\n";

    PCFreq = double(li.QuadPart)/1000.0;

    QueryPerformanceCounter(&li);
    CounterStart = li.QuadPart;
}
double GetCounter()
{
    LARGE_INTEGER li;
    QueryPerformanceCounter(&li);
    return double(li.QuadPart-CounterStart)/PCFreq;
}

int main()
{
    StartCounter();
    Sleep(1000);
    cout << GetCounter() <<"\n";
    return 0;
}

Ce programme devrait sortir un certain nombre de 1000 (mise en veille de windows n'est pas précis, mais il devrait ressembler à 999).

Le StartCounter() fonction enregistre le nombre de graduations du compteur de performance a dans le CounterStart variable. Le GetCounter() renvoie le nombre de millisecondes écoulées depuis le StartCounter() a été appelé en dernier comme un double, donc si GetCounter() renvoie 0.001 puis il a été d'environ 1 microseconde depuis StartCounter() a été appelé.

Si vous voulez avoir le timer secondes au lieu ensuite modifier

PCFreq = double(li.QuadPart)/1000.0;

pour

PCFreq = double(li.QuadPart);

ou si vous le souhaitez microsecondes ensuite utiliser

PCFreq = double(li.QuadPart)/1000000.0;

Mais c'est vraiment une question de commodité, car il renvoie un double.

20voto

Inge Henriksen Points 3068

J’ai utiliser ces définit :

Utilisation (supports pour empêcher redéfinit) :

Sortie de l’exemple d’utilisation :

11voto

Ed Briggs Points 131

Nous avons récemment mis à jour la documentation de QueryPerformanceCounter et l’utilisation correcte des informations supplémentaires ajoutées et les réponses aux FAQ. Vous pouvez trouver la documentation actualisée ici

http://msdn.Microsoft.com/en-US/Library/Windows/Desktop/dn553408 (v=vs.85).aspx

Ed Briggs Microsoft Corporation

2voto

Alex Martelli Points 330805

En supposant que vous êtes sur Windows (si vous devez marquer votre question en tant que tel!), sur cette page MSDN , vous pouvez trouver la source pour une solution simple, utile, HRTimer C++ de la classe qui encapsule le système nécessaires appelle à faire quelque chose de très proche de ce que vous avez besoin (il serait facile d'ajouter un GetTicks() méthode, en particulier, à faire exactement ce que vous avez besoin).

Sur les plateformes non-Windows, il n'y a pas de fonction QueryPerformanceCounter, de sorte que la solution ne sera pas directement portable. Toutefois, si vous ne l'envelopper dans une classe tels que mentionnés ci- HRTimer, il sera plus facile de modifier l'implémentation de la classe à utiliser ce que la plate-forme actuelle est en effet en mesure d'offrir (peut-être via Boost ou que ce soit!).

1voto

kagali-san Points 560

J’ai étendrait cette question avec un exemple de pilote NDIS sur l’obtention de temps. Comme on le sait, KeQuerySystemTime (imité sous NdisGetCurrentSystemTime) a une faible résolution supérieures millisecondes, et il y a certains processus tels que les paquets réseau ou autres IRP qui peut-être nécessiter un timestamp mieux ;

L’exemple est tout aussi simple :

Lorsque le diviseur est 10 ^ 3 ou 10 ^ 6 selon la résolution requise.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X