Nanosecond timing on OS X

Mac OSX specific forum
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3942
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Nanosecond timing on OS X

Post by wilbert »

I usually use ElapsedMilliseconds() on OS X to time a routine.
If you want a more accurate result, you can use UpTime() which returns the up time of the computer or mach_absolute_time() which is a bit faster.

Code: Select all

ImportC "/System/Library/Frameworks/CoreServices.framework/CoreServices"
  UpTime.q()
  AbsoluteDeltaToNanoseconds.q(end_time.q, start_time.q)
EndImport
  
start_time.q = UpTime()
; ... 
end_time.q = UpTime()
nano_seconds.q = AbsoluteDeltaToNanoseconds(end_time, start_time)
Even if you divide the result by 1,000,000 to get milliseconds, the result seems to be more accurate compared to ElapsedMilliseconds().
After a while ElapsedMilliseconds() runs behind a little.

Alternative (faster) approach ...

Code: Select all

ImportC "/System/Library/Frameworks/CoreServices.framework/CoreServices"
  mach_absolute_time.q()
  AbsoluteDeltaToNanoseconds.q(end_time.q, start_time.q)
EndImport
  
start_time.q = mach_absolute_time()
; ... 
end_time.q = mach_absolute_time()
nano_seconds.q = AbsoluteDeltaToNanoseconds(end_time, start_time)
User avatar
J. Baker
Addict
Addict
Posts: 2181
Joined: Sun Apr 27, 2003 8:12 am
Location: USA
Contact:

Re: Nanosecond timing on OS X

Post by J. Baker »

Very nice, thanks Wilbert!
www.posemotion.com

PureBasic Tools for OS X: PureMonitor, plist Tool, Data Maker & App Chef


Even the vine knows it surroundings but the man with eyes does not.
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3942
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: Nanosecond timing on OS X

Post by wilbert »

Here's also a simple procedure if you want microseconds

Code: Select all

ImportC ""
  mach_absolute_time.q()
  mach_timebase_info(*info)
EndImport

Procedure.q ElapsedMicroseconds(); microseconds as quad
  Static c.d = 0
  If c = 0
    mach_timebase_info(@c)
    c = 1e-3 * PeekL(@c) / PeekL(@c + 4)
  EndIf
  ProcedureReturn mach_absolute_time() * c
EndProcedure

Procedure.d ElapsedTime(); seconds as double
  Static base.q, c.d = 0
  If c = 0
    mach_timebase_info(@c)
    c = 1e-9 * PeekL(@c) / PeekL(@c + 4)
    base = mach_absolute_time()
  EndIf
  ProcedureReturn (mach_absolute_time() - base) * c
EndProcedure
User avatar
J. Baker
Addict
Addict
Posts: 2181
Joined: Sun Apr 27, 2003 8:12 am
Location: USA
Contact:

Re: Nanosecond timing on OS X

Post by J. Baker »

Cool, this seems to solve the stuttering issue that SetFrameRate() causes.

Code: Select all

ImportC ""
  mach_absolute_time.q()
  mach_timebase_info(*info)
EndImport

Procedure.d ElapsedTime(); seconds as double
  Static base.q, c.d = 0
  If c = 0
    mach_timebase_info(@c)
    c = 1e-9 * PeekL(@c) / PeekL(@c + 4)
    base = mach_absolute_time()
  EndIf
  ProcedureReturn (mach_absolute_time() - base) * c
EndProcedure

InitSprite()

OpenWindow(0, 0, 0,1280, 720, "Scroll", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget)
OpenWindowedScreen(WindowID(0), 0, 0, 1280, 720, 0, 0, 0, 0)

  CreateSprite(1, 128, 128)
   StartDrawing(SpriteOutput(1))
    DrawingMode(#PB_2DDrawing_Default)
     Box(0, 0, 128, 128, RGB(0, 0, 220))
   StopDrawing()
   
   X.w = 0
   start_time.d = ElapsedTime()
   
Repeat
 
  Event = WindowEvent()
    
      FlipBuffers()
      ClearScreen(RGB(235, 235, 235))
     
      DisplaySprite(1, X, 360 - 64)
      
    end_time.d = ElapsedTime() - start_time.d
 
    If end_time.d > 0.01
      X + 4
      start_time.d = ElapsedTime()
    EndIf
 
  If X >= 1280
     X = 0 -128
  EndIf
 
Until Event = #PB_Event_CloseWindow
www.posemotion.com

PureBasic Tools for OS X: PureMonitor, plist Tool, Data Maker & App Chef


Even the vine knows it surroundings but the man with eyes does not.
Post Reply