Question

Sous Win32, existe-t-il un moyen d’obtenir un nombre unique de cycles cpu ou quelque chose de similaire qui serait uniforme pour plusieurs processus / langues / systèmes / etc.

Je crée des fichiers journaux, mais je dois produire plusieurs fichiers journaux, car nous hébergeons le runtime .NET, et j'aimerais éviter d'appeler de l'un à l'autre pour vous connecter. En tant que tel, je pensais que je produirais simplement deux fichiers, les combinerais, puis les trier, pour obtenir un calendrier cohérent impliquant des appels inter-mondiaux.

Toutefois, GetTickCount n'augmente pas à chaque appel. Ce n'est donc pas fiable. Existe-t-il un meilleur numéro pour que je puisse recevoir les appels dans le bon ordre lors du tri?

Modifier : grâce à @Greg qui m'a mis sur la bonne voie pour QueryPerformanceCounter , qui a fait le tour.

Était-ce utile?

La solution

Vous pouvez utiliser l'instruction RDTSC (en supposant que x86). Cette instruction donne le compteur de cycle de l’UC, mais sachez qu’elle augmentera très rapidement jusqu’à sa valeur maximale puis qu'elle sera réinitialisée à 0. Comme le mentionne l’article Wikipedia, il serait peut-être préférable d’utiliser le fonction QueryPerformanceCounter .

Autres conseils

Voici un article intéressant! dit de ne pas utiliser RDTSC, mais de utilisez plutôt QueryPerformanceCounter .

Conclusion:

  

Utiliser des vieux timeGetTime() classiques à faire   le timing n'est pas fiable sur beaucoup   Systèmes d'exploitation Windows   parce que la granularité du système   la minuterie peut atteindre 10-15   millisecondes, ce qui signifie que   timeBeginPeriod(1) n’est précis que pour   10-15 millisecondes. [Notez que le   granularités élevées se produisent sur NT-basé   systèmes d'exploitation tels que Windows NT,   2000 et XP. Windows 95 et 98 ont tendance   d'avoir une bien meilleure granularité,   environ 1-5 ms.]

     

Cependant, si vous appelez   timeEndPeriod(1) au début de   votre programme (et Sleep() à   la fin), Sleep(1) sera généralement   devenir précis à 1-2 millisecondes,   et vous fournira extrêmement   informations de synchronisation précises.

     

Sleep(2) se comporte de la même manière; la durée   de temps que QueryPerformanceFrequency dort réellement   pour va main dans la main avec le   granularité de QueryPerformanceCounter, donc après   appeler <=> une fois,   <=> dormira réellement pour 1-2   millisecondes, <=> pendant 2-3, etc.   on (au lieu de dormir par incréments   jusqu'à 10-15 ms).

     

Pour un chronométrage plus précis   (précision inférieure à la milliseconde), vous   vouloir probablement éviter d'utiliser le   mnémonique d'assemblage RDTSC parce qu'il est   difficile à calibrer ; à la place, utilisez   <=> et   <=> qui sont   précis à moins de 10 microsecondes   (0,00001 secondes).

     

Pour un minutage simple, les deux timeGetTime   et QueryPerformanceCounter fonctionnent bien,   et QueryPerformanceCounter est   évidemment plus précis. Toutefois, si   vous devez faire n'importe quel type de " chronométré   pauses " (tels que ceux nécessaires pour   limite de framerate), vous devez être   attention à rester assis dans une boucle   QueryPerformanceCounter, en attente de   atteindre une certaine valeur; cette volonté   consommer 100% de votre processeur.   Au lieu de cela, considérons un schéma hybride,   où vous appelez Sleep (1) (n'oubliez pas   timeBeginPeriod (1) first!) à chaque fois   vous devez passer plus de 1 ms de   temps, puis entrez seulement le   Boucle QueryPerformanceCounter à 100%   pour finir le dernier < 1 / 1000ème de   seconde du délai dont vous avez besoin. Ce   vous donnera des délais ultra précis   (précis à 10 microsecondes), avec   utilisation du processeur très minime. Voir le code   ci-dessus.

System.Diagnostics.Stopwatch.GetTimestamp () renvoie le nombre de cycles du processeur depuis le début de l'heure (peut-être au démarrage de l'ordinateur, mais je ne suis pas sûr) et je ne l'ai jamais vu n'augmenter entre 2 appels.

Les cycles de la CPU seront spécifiques à chaque ordinateur. Vous ne pouvez donc pas l'utiliser pour fusionner le fichier journal de 2 ordinateurs.

La sortie RDTSC peut dépendre de la fréquence d'horloge du cœur actuel, qui n'est ni constante ni cohérente pour les CPU modernes.

Utilisez l'heure du système. Si vous utilisez des flux provenant de plusieurs systèmes, utilisez une source de temps NTP. Vous pouvez ainsi obtenir des lectures de temps fiables et cohérentes; si les frais généraux sont trop importants pour vous, utilisez HPET pour calculer le temps écoulé depuis la La dernière lecture fiable du temps connu est meilleure que l’utilisation du HPET seul.

Utilisez GetTickCount et ajoutez un autre compteur lors de la fusion des fichiers journaux. Vous ne obtiendrez pas une séquence parfaite entre les différents fichiers journaux, mais tous les journaux de chaque fichier seront au moins conservés dans le bon ordre.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top