Page 1 of 1

QueryPerformanceCounter() not returning millisecs ?!?!

Posted: Tue Apr 04, 2006 8:34 am
by nco2k

Code: Select all

QueryFreq.q
QueryCount1.q
QueryCount2.q
tgtCount1.l
tgtCount2.l

DisableDebugger

timeBeginPeriod_(1)

If QueryPerformanceFrequency_(@QueryFreq)
  QueryPerformanceCounter_(@QueryCount1)
  Delay(500)
  QueryPerformanceCounter_(@QueryCount2)
EndIf

tgtCount1 = timeGetTime_()
Delay(500)
tgtCount2 = timeGetTime_()

timeEndPeriod_(1)

EnableDebugger

Debug "Hardware Timer: "+Str(QueryCount2 - QueryCount1)
Debug "Software Timer: "+Str(tgtCount2 - tgtCount1)
the software timer returns here correctly the 500ms, but the hardware timer returns ~1457359560 here. whats that value?! this cant be millisecs, shouldnt QueryPerformanceCounter() return millisecs or have i missed something?? Image

c ya,
nco2k

Posted: Tue Apr 04, 2006 9:06 am
by maw
You have missed something :lol: Always read MSDN first :twisted:

http://msdn.microsoft.com/library/defau ... ounter.asp

The high resolution PerformanceCounter gives you "counts per second" which with todays CPUs is several million counts per second. QueryPerformanceFrequency_() returns the number of "counts per second" the hardware you are running on is capable of.

Together with QueryPerformanceCounter_() you have a timer resolution that on the fastest CPUs will be in the nanoseconds range. Very nice for benchmarking single instructions :P

Posted: Tue Apr 04, 2006 9:21 am
by netmaestro
QueryPerformanceFrequency returns the maximum number of slices you can cut one second into. It's usually a very high number, around four million on my machine. To get an accurate timeslice equal to one millisecond, you divide that number by 1000 and that is what you will test using QueryPerformanceCounter to see if a millisecond has gone by yet.

Here's a procedure that accurately returns ticks at a resolution of one ms: (by rescator)

Code: Select all

Procedure.l TicksHQ() 
  Static maxfreq.q 
  Protected t.q 
  If maxfreq=0 
    QueryPerformanceFrequency_(@maxfreq) 
    maxfreq=maxfreq/1000 
  EndIf 
  QueryPerformanceCounter_(@t.q) 
  ProcedureReturn t/maxfreq 
EndProcedure 
Divide maxfreq by 10000 instead of 1000 if you want tenths of a millisecond.

Usage:

Code: Select all

t=TicksHQ()
Repeat
  t2=TicksHQ
  If t2-t
    ; a millisecond has passed
    ; do some stuff
    t=t2
  EndIf
Until PureBasic 4.0 is released

Posted: Tue Apr 04, 2006 9:31 am
by dagcrack
Well, by not discounting the function overhead you're trashing the accuracy if you were using a higher res.

You're also dividing.. got an if statement in there...etc. big overhead if you ask.

Posted: Tue Apr 04, 2006 9:35 am
by netmaestro
Theoretically, yes. But from a practical standpoint, at res's of up to 1/10 ms the function overhead is not significant enough to impact accuracy. Res's much higher than that are not practical for much, afaik. You can't get FPS anywhere near that, for example. My testing shows no degradation of accuracy that would impact a practical application of the counter. But - you're more than welcome to improve on it!

Posted: Tue Apr 04, 2006 9:38 am
by nco2k
thanks guys for clearing this up and thanks netmaestro for the example code, this will become pretty handy. now i have a better idea of how to use this great highres counter. :wink:

c ya,
nco2k

Posted: Tue Apr 04, 2006 10:03 am
by dagcrack
Of course at that res theres no problem, I just pointed out that there is an overhead .. For benchmarking purposes it would be cool if you took the overhead into account and reduced it from the result value.

I just like to see things well done even if sometimes theres not a big difference :oops:

Re: QueryPerformanceCounter() not returning millisecs ?!?!

Posted: Wed Jun 13, 2012 2:33 pm
by chris319

Code: Select all

maxfreq.q: a.q: b.q: t_total.d = 0: t_average.d

QueryPerformanceFrequency_(@maxfreq)
maxfreq / 1000

For ct = 1 To 100

QueryPerformanceCounter_(@a.q)
Delay(20)
QueryPerformanceCounter_(@b.q)

t_total + (b - a) / maxfreq
t_average = t_total / ct

Debug "Average: " + StrD(t_average, 3) + " milliseconds"

Next