views:

109

answers:

2
LARGE_INTEGER lpPerformanceCount, lpFrequency;

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

(Count.QuadPart is a long long showing a CPU count)

(Freq.QuadPart is a long long showing frequency of Count for a second)

Attempting to print microseconds in real time.

stable output:

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

erratic output: (result jumps incoherently front and back even if it's at first glance sane)

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

EDIT: printf needed a further (unsigned long long) conversion in its input, the original code had that done by a return value of a func.

+1  A: 

Are you sure %llu prints a reasonable double?

lpPerformanceCount.QuadPart / lpFrequency.QuadPart gives you a time, rounded to full seconds.

lpPerformanceCount.QuadPart % lpFrequency.QuadPart gives you a tick count (number ticks since last full second).

Adding a count to a time gives you.. how to put that politely... crap.

I alway use the double arithmetics, much less hassle. However, if you insist in non-FPU code, you could use:

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

which would overflow faster (though not a practical problem I'd assume). Fixing that up for integer arithmetics:

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

(I hope that's right...)

peterchen
What do you think is the safest way to convert them for that purpose? Is unsigned long long var = ((long double)lpPerformanceCount.QuadPart/ lpFrequency.QuadPart) * 1000000) the best? (or with 1000000ULL)
Lela Dax
I store `1.0/freq.QuadPart` as time-per-tick, and use `count.QuadPart*timePerTick` for a time (in seconds). There is a theoretical loss of precision - but I've never seen frequency values that would be affected.
peterchen
I guess that's pretty much equivalent for the hardware since floating point arithmetic gets into play. Thanks for the input.
Lela Dax
+1  A: 

Yes. IIUC, it should be something like:

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

or maybe

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

The first will overflow if lpFreuency.QuadPart is high; the second will be inaccurate or even overflow if lpFrequency.QuadPart is low.

jpalecek