| View previous topic :: View next topic |
| Author |
Message |
Martin Sedlak
Joined: 26 Nov 2010 Posts: 701
|
Post subject: microsecond-accurate timing on Windows Posted: Mon May 28, 2012 10:20 am |
|
|
I have been thinking recently about time measurement in Windows.
GetTickCount (has granularity of ~15 msec which is bad)
timeGetTime depends on last period set using with timeBeginPeriod,
the docs say it is system-global, so if an app uses timeBeginPeriod(40)
while your program is running, you immediately get worse granularity
than GetTickCount. Also it is said that this affects thread scheduling so better keep hands off it.
QueryPerformanceCounter/QueryPerformanceFrequency:
ultra high resolution, if i remember these calls used to take longer than GetTickCount. Not always available.
rdtsc instruction: very fast but there may be problems with multiple cores and dynamic changes in CPU freq, nonportable
Are there better alternatives I missed?
Now what if I wanted to measure in microseconds instead of some units (usually close to CPU clock freq) which QPF provides?
Here's my solution using QPC/QPF. Note that it's fairly slow on a 32-bit machine here, getMicrosec() itself takes about 1-2 microseconds here () which is already a lot.
Anyway, here's my solution with implementation in case it's useful to someone: (left out some impl. details but I guess it's self-explanatory)
| Code: |
static volatile signed char init = 0;
static i64 freq;
static u32 shortFreq;
static i64 lastTick;
static i64 remainder = 0;
static i64 emul = 0;
static Mutex usMutex;
static Mutex gMutex;
static i32 lastTC;
i64 getMicrosec()
{
if ( init == -1 )
{
LARGE_INTEGER tmp;
QueryPerformanceCounter( &tmp );
i64 cur = (i64)tmp.QuadPart;
{
MutexLock _( usMutex );
i64 delta = cur - lastTick + remainder;
i64 us = delta * 1000000 / shortFreq;
emul += us;
remainder = delta - us * freq / 1000000;
lastTick = cur;
return emul;
}
}
if ( init == 1 )
{
LARGE_INTEGER tmp;
QueryPerformanceCounter( &tmp );
i64 cur = (i64)tmp.QuadPart;
{
MutexLock _( usMutex );
i64 delta = cur - lastTick + remainder;
i64 us = delta * 1000000 / freq;
emul += us;
remainder = delta - us * freq / 1000000;
lastTick = cur;
return emul;
}
}
if ( init == 2 )
{
MutexLock _( usMutex );
i32 cur = (i32)GetTickCount();
i32 delta = cur - lastTC;
i64 tmp = (i64)delta * 1000;
lastTC = cur;
return emul += tmp;
}
// initialize
MutexLock _( gMutex );
LARGE_INTEGER frq;
if ( QueryPerformanceFrequency( &frq ) == FALSE )
{
// not available => use milisec emulation
init = 2;
lastTC = GetTickCount();
} else {
freq = (i64)frq.QuadPart;
LARGE_INTEGER tmp;
QueryPerformanceCounter( &tmp );
lastTick = (i64)tmp.QuadPart;
if ( freq <= 0xffffffffU )
{
shortFreq = (u32)freq;
init = -1;
}
else
{
init = 1;
}
}
return getMicrosec();
}
i32 getMillisec()
{
return (i32)(getMicrosec()/1000 & 0xffffffffU);
}
|
Basically what this does is similar to GetTickCount except that it has a microsecond resolution and uses 64-bit output counter. And getMillisec() is a 1-millisecond accurate version.
Of course if perfcounter is not available the code falls back to emulation using GetTickCount(). |
|
| Back to top |
|
 |
|
| Subject |
Author |
Date/Time |
microsecond-accurate timing on Windows |
Martin Sedlak |
Mon May 28, 2012 10:20 am |
Re: microsecond-accurate timing on Windows |
Martin Sedlak |
Mon May 28, 2012 12:56 pm |
Re: microsecond-accurate timing on Windows |
Vincent Diepeveen |
Mon May 28, 2012 2:44 pm |
Re: microsecond-accurate timing on Windows |
Martin Sedlak |
Mon May 28, 2012 3:22 pm |
Re: microsecond-accurate timing on Windows |
Vincent Diepeveen |
Mon May 28, 2012 3:30 pm |
Re: microsecond-accurate timing on Windows |
Martin Sedlak |
Mon May 28, 2012 5:10 pm |
Re: microsecond-accurate timing on Windows |
Vincent Diepeveen |
Mon May 28, 2012 7:05 pm |
Re: microsecond-accurate timing on Windows |
Martin Sedlak |
Mon May 28, 2012 3:36 pm |
Re: microsecond-accurate timing on Windows |
Vincent Diepeveen |
Mon May 28, 2012 3:39 pm |
Re: microsecond-accurate timing on Windows |
Martin Sedlak |
Mon May 28, 2012 5:20 pm |
Re: microsecond-accurate timing on Windows |
Vincent Diepeveen |
Mon May 28, 2012 6:23 pm |
Re: microsecond-accurate timing on Windows |
Martin Sedlak |
Mon May 28, 2012 7:13 pm |
Re: microsecond-accurate timing on Windows |
Vincent Diepeveen |
Mon May 28, 2012 7:18 pm |
Re: microsecond-accurate timing on Windows |
Martin Sedlak |
Mon May 28, 2012 8:33 pm |
Re: microsecond-accurate timing on Windows |
Aleks Peshkov |
Tue May 29, 2012 7:50 am |
Re: microsecond-accurate timing on Windows |
Martin Sedlak |
Tue May 29, 2012 8:26 am |
Re: microsecond-accurate timing on Windows |
Vincent Diepeveen |
Mon May 28, 2012 7:37 pm |
Re: microsecond-accurate timing on Windows |
Martin Sedlak |
Mon May 28, 2012 8:07 pm |
Re: microsecond-accurate timing on Windows |
Vincent Diepeveen |
Tue May 29, 2012 12:44 pm |
Re: microsecond-accurate timing on Windows |
Martin Sedlak |
Tue May 29, 2012 1:15 pm |
Re: microsecond-accurate timing on Windows |
Vincent Diepeveen |
Tue May 29, 2012 3:07 pm |
Re: microsecond-accurate timing on Windows |
Martin Sedlak |
Tue May 29, 2012 4:38 pm |
Re: microsecond-accurate timing on Windows |
Vincent Diepeveen |
Tue May 29, 2012 12:55 pm |
Re: microsecond-accurate timing on Windows |
Vincent Diepeveen |
Tue May 29, 2012 1:11 pm |
Re: microsecond-accurate timing on Windows |
Martin Sedlak |
Tue May 29, 2012 1:29 pm |
Re: microsecond-accurate timing on Windows |
Vincent Diepeveen |
Tue May 29, 2012 3:18 pm |
Re: microsecond-accurate timing on Windows |
Martin Sedlak |
Tue May 29, 2012 5:00 pm |
Re: microsecond-accurate timing on Windows |
Wylie Garvin |
Tue May 29, 2012 9:38 pm |
Re: microsecond-accurate timing on Windows |
Vincent Diepeveen |
Tue May 29, 2012 9:48 pm |
Re: microsecond-accurate timing on Windows |
Martin Sedlak |
Wed May 30, 2012 9:10 am |
Re: microsecond-accurate timing on Windows |
Vincent Diepeveen |
Fri Jun 01, 2012 9:24 am |
Re: microsecond-accurate timing on Windows |
Martin Sedlak |
Fri Jun 01, 2012 10:52 am |
Re: microsecond-accurate timing on Windows |
Vincent Diepeveen |
Sat Jun 02, 2012 3:36 pm |
Re: microsecond-accurate timing on Windows |
Martin Sedlak |
Sun Jun 03, 2012 7:45 am |
Re: microsecond-accurate timing on Windows |
Vincent Diepeveen |
Mon Jun 04, 2012 11:25 am |
Re: microsecond-accurate timing on Windows |
Vincent Diepeveen |
Mon Jun 04, 2012 11:39 am |
Re: microsecond-accurate timing on Windows |
Martin Sedlak |
Mon Jun 04, 2012 12:31 pm |
Re: microsecond-accurate timing on Windows |
Martin Sedlak |
Mon Jun 04, 2012 12:12 pm |
Re: microsecond-accurate timing on Windows |
Martin Sedlak |
Wed May 30, 2012 9:13 am |
Re: microsecond-accurate timing on Windows |
Vincent Diepeveen |
Fri Jun 01, 2012 9:29 am |
Re: microsecond-accurate timing on Windows |
Martin Sedlak |
Tue May 29, 2012 5:25 pm |
Re: microsecond-accurate timing on Windows |
Vincent Diepeveen |
Tue May 29, 2012 7:19 pm |
Re: microsecond-accurate timing on Windows |
Martin Sedlak |
Wed May 30, 2012 11:41 am |
Re: microsecond-accurate timing on Windows |
Thomas Petzke |
Wed May 30, 2012 2:57 pm |
Re: microsecond-accurate timing on Windows |
Vincent Diepeveen |
Tue May 29, 2012 7:27 pm |
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|