• ### Popular Now

• 13
• 15
• 19
• 27
• 9

#### Archived

This topic is now archived and is closed to further replies.

# High-resolution timers.

This topic is 5465 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Does anyone know how (or know of a tutorial that explains how) to add system timers in WindowsXP that are higher resolution than Windows''s base 30 times/sec timer (say 200 times/second). I don''t want to use MFC or anything, just raw C. I''m trying to do ping-variation analysis, and 30x/second is just not good enough. Thanks for all assistance. Simon Hill.

##### Share on other sites
Look up QueryPerformanceCounter() in the MSDN.

Its much higher frequency than timeGetTime() or WM_TIMER.

##### Share on other sites
x586 rdtsc opcode, returns the CPU ticks into edx:eax
On a 1GHz computer it has 1ns resolution.

##### Share on other sites
If you use rdtsc then keep in mind that you''ll also have to calculate the CPU frquency. And I havent seen a 100% accurate way of getting the exact speed. It''s always off by a wee bit, and on laptops it gets worse cause they can change their speed in real time.

SO while rdtsc definetly has the best execution speed and accuracy overall. Converting it to seconds is dodgy business. Use QueryPerformanceCounter for solid and high frequency timing. Although this is not a purely c function.

heh....what to do, what to do...

:::: [ Triple Buffer V2.0 ] ::::

##### Share on other sites
QueryPerf has the same problem on Win2k & WinXP on laptops But it goes and checks for it, so the call ends-up being really slow.

##### Share on other sites
I use QuereyPerformanceCounter and here is some code that should be able to help you out.

timeElapsed is the time since the last call to timerUpdate(). currentTime is the time since timerInit() was called. Those are the variables that are helpful to outside files. I just extern them so other files can use those variables.

    __int64 g_currentCount = 0;__int64 g_lastCount = 0;__int64 g_baseCount = 0;double g_rateInverse = 0.0;float g_lastTime = 0.0;float timeElapsed = 0.0;float currentTime = 0.0;bool timerInit(){	__int64 rate;	if (!QueryPerformanceFrequency((LARGE_INTEGER*)&rate)) return false;	//Retrieve the frequency	if (!rate) return false;	g_rateInverse=1.0/(double)rate;		//Precalculate the rate inverse so we don't have to do division	if (!QueryPerformanceCounter((LARGE_INTEGER*)&g_baseCount)) return false;	//Get the starting time	g_lastCount = g_baseCount;		//Set the last count so we can do elapsed time	g_lastTime = 0.0;	return true; // there is a clock}void timerUpdate(){	do	{		QueryPerformanceCounter((LARGE_INTEGER*)&g_currentCount);	//Keep querying the current count until it changes			}	while( g_currentCount-g_lastCount == 0 );	currentTime = (float)((double)(g_currentCount - g_baseCount) * (double)g_rateInverse);	timeElapsed = currentTime - g_lastTime;	g_lastCount = g_currentCount;	g_lastTime = currentTime;}

--- COMPUTABILITY ---

[edited by - Computability on March 31, 2003 7:50:21 PM]

##### Share on other sites
Check out SetWaitableTimer.

quote:
QueryPerf has the same problem on Win2k & WinXP on laptops But it goes and checks for it, so the call ends-up being really slow.

Really? On my system (2k SP3, desktop), it uses the PCI timer (3x PIT freq). What makes it slow (order of several µs) is port I/O.

##### Share on other sites
quote:
Original post by Jan Wassenberg
Really? On my system (2k SP3, desktop), it uses the PCI timer (3x PIT freq). What makes it slow (order of several µs) is port I/O.

It can use various methods (acording to the docs, it''s processor dependant). Mine appears to use CPU frequency, as I get a QueryPerformanceFrequency() that''s almost equal to my CPU clock speed...

If I had my way, I''d have all of you shot!

codeka.com - Just click it.

##### Share on other sites
Nobody mentioned mmtimers. Is there a reason for this? :-(