Hi-res timing delayer

Share your advanced PureBasic knowledge/code with the community.
User avatar
Psychophanta
Always Here
Always Here
Posts: 5153
Joined: Wed Jun 11, 2003 9:33 pm
Location: Anare
Contact:

Hi-res timing delayer

Post by Psychophanta »

Code: Select all

;-determine timer max resolution:
If QueryPerformanceFrequency_(Freq.LARGE_INTEGER)
  periodns.f=1000000000/(Pow(2,32)*Freq\highpart+Freq\lowpart)
  ;MessageRequester("","Resolution (used time per tick) in this machine is: "+Str(periodns)+" nanosecs")
Else
  MessageRequester("","No High-res timer allowed"):End
EndIf

;-determine API call and other stuff delay:
!fldz
!fldz
QueryPerformanceCounter_(t1.LARGE_INTEGER)
     ;Same stuff than below (needed to determine the time amount used by testing process):
!fild qword[v_t1]
!fsub st0,st1
!fcomip st2
!jc @f
!@@:
!fstp st0
!fstp st0
QueryPerformanceCounter_(t2.LARGE_INTEGER)
calldelay.LARGE_INTEGER\lowpart = t2\lowpart - t1\lowpart
;MessageRequester("","API call used time was ~ "+StrF(calldelay\lowpart*periodns)+" nanosecs") 


;-perform hires-timing delay:
Standby.f=ValF(InputRequester("","Input wished delay time in milliseconds","0.655"))
Standby.f*1000000;    <- pass nanosecs to millisecs

!fld dword[v_Standby]
!fdiv dword[v_periodns]; <-now in st0 is the #ticks to perform
QueryPerformanceCounter_(t1.LARGE_INTEGER)
!fild qword[v_t1]   ;<-now in st0 is checkpoint1,in st1 is #ticks
!fsub qword[v_calldelay]  ;<-substract the time used by QueryPerformanceCounter_() function call
!@@:
QueryPerformanceCounter_(t2.LARGE_INTEGER)
!fild qword[v_t2] ;<-now in st0 is checkpoint2, in st1 is checkpoint1 and in st2 is #ticks
!fsub st0,st1   ;<- checkpoint2 - checkpoint1 - calldelay to st0
!fcomip st2     ;<-compare #ticks
!jc @r          ;<-continue polling until #ticks is reached
!fstp st0
!fstp st0


MessageRequester("","That's it!")
Corrected for final, i hope.
I don't know if it can be done even more accurate :)
http://www.zeitgeistmovie.com

while (world==business) world+=mafia;
eriansa
Enthusiast
Enthusiast
Posts: 277
Joined: Wed Mar 17, 2004 12:31 am
Contact:

Post by eriansa »

could by very usefull. Thanks!
vanleth
User
User
Posts: 79
Joined: Sat Jun 28, 2003 4:39 am
Location: Denmark - Valby

Post by vanleth »

great stuff, thanks
User avatar
Psychophanta
Always Here
Always Here
Posts: 5153
Joined: Wed Jun 11, 2003 9:33 pm
Location: Anare
Contact:

Re: Hi-res timing delayer

Post by Psychophanta »

Hi-res timming stuff:

Code: Select all

; determine timer max resolution:
If QueryPerformanceFrequency_(@Freq.q)
  If Freq<0:Freq!$8000000000000000:periodns.d=Freq:periodns+$7fffffffffffffff+1:periodns=1E9/periodns
  Else:periodns=1E9/Freq
  EndIf
  MessageRequester("Timing resolution info","Resolution (used time per tick) in this machine is: "+StrD(periodns)+" nanosecs")
Else
  MessageRequester("Sorry!","No High-res timer allowed by this machine"):End
EndIf

; determine API call delay:
QueryPerformanceCounter_(@t1.q)
QueryPerformanceCounter_(@t2.q)
calldelay.q=t2-t1
MessageRequester("","Used time by API call QueryPerformanceCounter_() was ~ "+StrD(calldelay*periodns)+" nanosecs")

; determine for-next loop time:
QueryPerformanceCounter_(@t1.q)
For t=1 To 100000:Next
QueryPerformanceCounter_(@t2.q)
MessageRequester("","(For t=1 To 100000:Next) loop used time was ~ "+StrD((t2-t1-calldelay)*periodns)+" nanosecs")

; perform some microsecond delay:
#uSecDelay=188.765432
ticks.d=#uSecDelay/periodns
ticks*1E3
QueryPerformanceCounter_(@t1.q)
Repeat
  QueryPerformanceCounter_(@t2.q)
Until t2-t1+calldelay>=ticks
MessageRequester("End","~ "+StrD(periodns*(t2-t1+calldelay)/1E3)+" microseconds delayed")
http://www.zeitgeistmovie.com

while (world==business) world+=mafia;
Post Reply