2010-08-09 3 views
1
LARGE_INTEGER lpPerformanceCount, lpFrequency; 

QueryPerformanceCounter(&lpPerformanceCount); 
QueryPerformanceFrequency(&lpFrequency); 

(Count.QuadPart est un long montrant un nombre de CPU)Quelqu'un peut-il déchiffrer pourquoi ces deux conversions à non signé longtemps donner des résultats différents?

(Freq.QuadPart est une fréquence du comte montrant long long pour une seconde)

Toute tentative d'impression microsecondes en temps réel.

sortie stable:

printf("%llu\n", ((long double)lpPerformanceCount.QuadPart/ lpFrequency.QuadPart) * 1000000); 

sortie erratique: (résultat des sauts incohérents avant et arrière, même si elle est au premier coup d'œil sain d'esprit)

printf("%llu\n", 1000000 * (lpPerformanceCount.QuadPart/lpFrequency.QuadPart) + (lpPerformanceCount.QuadPart % lpFrequency.QuadPart)); 

EDIT: printf avait besoin d'un autre (unsigned long long) conversion dans son entrée, le code original avait cela fait par une valeur de retour d'une fonction.

Répondre

1

Êtes-vous sûr que %llu imprime un double raisonnable?

lpPerformanceCount.QuadPart/lpFrequency.QuadPart vous donne un temps, arrondi à la pleine seconde.

lpPerformanceCount.QuadPart % lpFrequency.QuadPart donne le nombre de ticks (nombre de ticks depuis la dernière seconde). Ajouter un compte à un temps vous donne .. comment mettre poliment ... merde.

J'utilise toujours le double arithmétique, et encore moins les tracas. Cependant, si vous insistez dans le code non-FPU, vous pouvez utiliser:

count.QuadPart*1000000/(freq.QuadPart*1000000) 

qui provoque un débordement plus rapide (mais pas un problème pratique je suppose). Fixation que pour Arithmétique entier:

count.QuadPart/freq.QuadPart 
+ (count.QuadPart % freq.QuadPart) * 1000000/freq.QuadPart 

(je espoir qui convient ...)

+0

Selon vous, quel est le moyen le plus sûr de les convertir à cette fin? Est unsigned long long var = ((long double) lpPerformanceCount.QuadPart/lpFrequency.QuadPart) * 1000000) le meilleur? (ou avec 1000000ULL) –

+0

Je stocke '1.0/freq.QuadPart' en time-per-tick, et utilise' count.QuadPart * timePerTick' pendant un certain temps (en secondes). Il y a une perte de précision théorique - mais je n'ai jamais vu de valeurs de fréquence qui seraient affectées. – peterchen

+0

Je suppose que c'est à peu près équivalent pour le matériel puisque l'arithmétique à virgule flottante entre en jeu. Merci pour la contribution. –

1

Oui. IIUC, il devrait être quelque chose comme:

1000000 * (lpPerformanceCount.QuadPart/lpFrequency.QuadPart) + 
(lpPerformanceCount.QuadPart % lpFrequency.QuadPart) * 1000000/lpFrequency.QuadPart 

ou peut-être

(lpPerformanceCount.QuadPart/(lpFrequency.QuadPart/1000000)) 

Le premier débordement de volonté si lpFreuency.QuadPart est élevé; le second sera inexact ou débordera même si lpFrequency.QuadPart est bas.

Questions connexes