QueryPerformanceCounter() not returning millisecs ?!?!

Just starting out? Need help? Post your questions and find answers here.
User avatar
nco2k
Addict
Addict
Posts: 1344
Joined: Mon Sep 15, 2003 5:55 am

QueryPerformanceCounter() not returning millisecs ?!?!

Post 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
If OSVersion() = #PB_OS_Windows_ME : End : EndIf
maw

Post 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
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post 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
Last edited by netmaestro on Tue Apr 04, 2006 9:32 am, edited 1 time in total.
BERESHEIT
dagcrack
Addict
Addict
Posts: 1868
Joined: Sun Mar 07, 2004 8:47 am
Location: Argentina
Contact:

Post 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.
! Black holes are where God divided by zero !
My little blog!
(Not for the faint hearted!)
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post 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!
Last edited by netmaestro on Tue Apr 04, 2006 9:47 am, edited 1 time in total.
BERESHEIT
User avatar
nco2k
Addict
Addict
Posts: 1344
Joined: Mon Sep 15, 2003 5:55 am

Post 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
If OSVersion() = #PB_OS_Windows_ME : End : EndIf
dagcrack
Addict
Addict
Posts: 1868
Joined: Sun Mar 07, 2004 8:47 am
Location: Argentina
Contact:

Post 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:
! Black holes are where God divided by zero !
My little blog!
(Not for the faint hearted!)
chris319
Enthusiast
Enthusiast
Posts: 782
Joined: Mon Oct 24, 2005 1:05 pm

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

Post 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
Post Reply