It is currently Thu Oct 17, 2019 10:30 pm

All times are UTC + 1 hour




Post new topic Reply to topic  [ 5 posts ] 
Author Message
 Post subject: HighResTimer - Module
PostPosted: Sun Aug 07, 2016 1:19 am 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Sun Jul 07, 2013 11:35 am
Posts: 400
Location: Canada
Hello everyone,

Another Module conversion, this time a HighResTimer.

Best regards
StarBootics
Code:
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Project name : HighResTimer - Module
; File Name : HighResTimer - Module.pb
; File version: 1.0.0
; Programming : OK
; Programmed by : StarBootics
; Date : 06-08-2016
; Last Update : 06-08-2016
; PureBasic code : V5.50
; Platform : Windows, Linux, MacOS X
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; This code was originally created by Guimauve to have a High Resolution
; Timer. See : http://www.purebasic.fr/english/viewtopic.php?f=15&t=49365
;
; I deserve credit only to convert the original code into a Module.
;
; This code is free to be use where ever you like but you use it at your
; own risk.
;
; The author can in no way be held responsible for data loss, damage or
; other annoying situations that may occur.
;
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

DeclareModule HighResTimer
 
  Declare Initialize()
  Declare Reset()
  Declare Start()
  Declare Stop()
  Declare.q Consult()
 
EndDeclareModule

Module HighResTimer
 
  CompilerSelect #PB_Compiler_OS
     
    CompilerCase #PB_OS_Linux
     
      #CLOCK_MONOTONIC = 1
     
      Structure TimeSpec Align #PB_Structure_AlignC
        Second.i
        NanoSecond.l
      EndStructure
     
      ImportC "-lrt"
        clock_gettime(ClockID.l, *TimeSpecA.TimeSpec)
      EndImport
     
    CompilerCase #PB_OS_MacOS
     
      Structure TimeBase Align #PB_Structure_AlignC
        Numerator.l
        Denominator.l
      EndStructure
     
      ImportC ""
        mach_absolute_time.q()
        mach_timebase_info(*TimeBaseA.TimeBase)
      EndImport
     
  CompilerEndSelect
 
  Structure Instance Align #PB_Structure_AlignC
   
    Stopped.b
    StartMicroSec.q
    StopMicroSec.q
   
    CompilerSelect #PB_Compiler_OS
       
      CompilerCase #PB_OS_Windows
        Frequency.q
        StartCount.q
        EndCount.q
       
      CompilerCase #PB_OS_Linux
        StartCount.TimeSpec
        EndCount.TimeSpec
       
      CompilerCase #PB_OS_MacOS
        MicroSecConversion.d
        TimeBase.TimeBase
        StartCount.q
        EndCount.q
       
    CompilerEndSelect
   
  EndStructure
 
  Global Instance.Instance
 
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< The New Operator <<<<<
 
  Procedure Initialize()
   
    Instance\Stopped = #True
    Instance\StartMicroSec = 0
    Instance\StopMicroSec = 0
   
    CompilerSelect #PB_Compiler_OS
       
      CompilerCase #PB_OS_Windows
        QueryPerformanceFrequency_(@Instance\Frequency)
        Instance\StartCount = 0
        Instance\EndCount = 0
       
      CompilerCase #PB_OS_Linux
        Instance\StartCount\Second = 0
        Instance\StartCount\NanoSecond = 0
        Instance\EndCount\Second = 0
        Instance\EndCount\NanoSecond = 0
       
      CompilerCase #PB_OS_MacOS
        mach_timebase_info(@Instance\TimeBase)
        Instance\MicroSecConversion = 1e-3 * Instance\TimeBase\Numerator / Instance\TimeBase\Denominator
        Instance\StartCount = 0
        Instance\EndCount = 0
       
    CompilerEndSelect
   
  EndProcedure
 
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< The Reset Operator <<<<<
 
  Procedure Reset()
   
    Instance\Stopped = 0
    Instance\StartMicroSec = 0
    Instance\StopMicroSec = 0
   
    CompilerSelect #PB_Compiler_OS
       
      CompilerCase #PB_OS_Windows
        Instance\Frequency = 0
        Instance\StartCount = 0
        Instance\EndCount = 0
       
      CompilerCase #PB_OS_Linux
        Instance\StartCount\Second = 0
        Instance\StartCount\NanoSecond = 0
        Instance\EndCount\Second = 0
        Instance\EndCount\NanoSecond = 0
       
      CompilerCase #PB_OS_MacOS
        Instance\MicroSecConversion = 0.0
        Instance\TimeBase\Numerator = 0
        Instance\TimeBase\Denominator = 0
        Instance\StartCount = 0
        Instance\EndCount = 0
       
    CompilerEndSelect
   
  EndProcedure
 
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< The Start operator <<<<<
 
  Procedure Start()
   
    Instance\Stopped = #False
   
    CompilerSelect #PB_Compiler_OS
       
      CompilerCase #PB_OS_Windows
        QueryPerformanceCounter_(@Instance\StartCount)
       
      CompilerCase #PB_OS_Linux
        clock_gettime(#CLOCK_MONOTONIC, @Instance\StartCount)
       
      CompilerCase #PB_OS_MacOS
        Instance\StartCount = mach_absolute_time() * Instance\MicroSecConversion
       
    CompilerEndSelect
   
  EndProcedure
 
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< The Stop operator <<<<<
 
  Procedure Stop()
   
    Instance\Stopped = #True
   
    CompilerSelect #PB_Compiler_OS
       
      CompilerCase #PB_OS_Windows
        QueryPerformanceCounter_(@Instance\EndCount)
       
      CompilerCase #PB_OS_Linux
        clock_gettime(#CLOCK_MONOTONIC, @Instance\EndCount)
       
      CompilerCase #PB_OS_MacOS
        Instance\EndCount = mach_absolute_time() * Instance\MicroSecConversion
       
    CompilerEndSelect
   
  EndProcedure
 
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< The Consult Operator <<<<<
 
  Procedure.q Consult()
   
    CompilerSelect #PB_Compiler_OS
       
      CompilerCase #PB_OS_Windows
       
        If Instance\Stopped = #False
          QueryPerformanceCounter_(@Instance\EndCount)
        EndIf
       
        Instance\StartMicroSec = Instance\StartCount * (1000000.0 / Instance\Frequency)
        Instance\StopMicroSec = Instance\EndCount * (1000000.0 / Instance\Frequency)
       
      CompilerCase #PB_OS_Linux
       
        If Instance\Stopped = #False
          clock_gettime(#CLOCK_MONOTONIC, @Instance\EndCount)
        EndIf
       
        Instance\StartMicroSec = Instance\StartCount\Second * 1000000 + Instance\StartCount\NanoSecond / 1000
        Instance\StopMicroSec = Instance\EndCount\Second * 1000000 + Instance\EndCount\NanoSecond / 1000
       
      CompilerCase #PB_OS_MacOS
       
        If Instance\Stopped = #False
          Instance\EndCount = mach_absolute_time() * Instance\MicroSecConversion
        EndIf
       
        Instance\StartMicroSec = Instance\StartCount
        Instance\StopMicroSec = Instance\EndCount
       
    CompilerEndSelect
   
    ProcedureReturn Instance\StopMicroSec - Instance\StartMicroSec
  EndProcedure
 
EndModule

CompilerIf #PB_Compiler_IsMainFile
 
  HighResTimer::Initialize() ; <-- Mandatory to Initialize the timer before using it
  HighResTimer::Start()
 
  Delay(1)
  Debug HighResTimer::Consult()
 
  Delay(5)
  Debug HighResTimer::Consult()
 
  Delay(499)
  Debug HighResTimer::Consult()
 
  Delay(500)
  Debug HighResTimer::Consult()
 
  Delay(1499)
  Debug HighResTimer::Consult()
 
  Delay(1501)
  Debug HighResTimer::Consult()
 
  HighResTimer::Stop()
  HighResTimer::Reset()
 
CompilerEndIf

; <<<<<<<<<<<<<<<<<<<<<<<
; <<<<< END OF FILE <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<

_________________
The Stone Age did not end due to a shortage of stones !


Last edited by StarBootics on Sun Aug 07, 2016 11:16 pm, edited 2 times in total.

Top
 Profile  
Reply with quote  
 Post subject: Re: HighResTimer - Module
PostPosted: Sun Aug 07, 2016 4:21 pm 
Offline
Enthusiast
Enthusiast

Joined: Fri Oct 16, 2009 10:12 am
Posts: 594
Location: BE
StarBootics I get six times a zero ?
Debug HighResTimer::Consult() ;all 0
Shouldn't it give the delta-timings ?
(XP SP3)

Thanks

_________________
Yeah I know, but keep in mind ... Leonardo da Vinci was also an autodidact.


Top
 Profile  
Reply with quote  
 Post subject: Re: HighResTimer - Module
PostPosted: Sun Aug 07, 2016 10:04 pm 
Offline
Addict
Addict
User avatar

Joined: Mon Jul 25, 2005 3:51 pm
Posts: 3585
Location: Utah, USA
Joris wrote:
StarBootics I get six times a zero ?
Debug HighResTimer::Consult() ;all 0
Shouldn't it give the delta-timings ?
(XP SP3)

The fractional parts of the calculation are being rounded to zero before multiplying to find the results. It can be corrected by making the following modification in the Consult() procedure to shift the calculation into using floats throughout the entire calculation:

Change this part:
Code:
CompilerSelect #PB_Compiler_OS
       
      CompilerCase #PB_OS_Windows
       
        If Instance\Stopped = #False
          QueryPerformanceCounter_(@Instance\EndCount)
        EndIf
       
        Instance\StartMicroSec = Instance\StartCount * (1000000 / Instance\Frequency)
        Instance\StopMicroSec = Instance\EndCount * (1000000 / Instance\Frequency)


to this:
Code:
CompilerSelect #PB_Compiler_OS
       
      CompilerCase #PB_OS_Windows
       
        If Instance\Stopped = #False
          QueryPerformanceCounter_(@Instance\EndCount)
        EndIf
       
        Instance\StartMicroSec = 0.0 + Instance\StartCount * (1000000 / Instance\Frequency) ; ***
        Instance\StopMicroSec = 0.0 + Instance\EndCount * (1000000 / Instance\Frequency) ; ***

_________________
Image


Top
 Profile  
Reply with quote  
 Post subject: Re: HighResTimer - Module
PostPosted: Mon Aug 08, 2016 7:51 am 
Offline
Enthusiast
Enthusiast

Joined: Fri Oct 16, 2009 10:12 am
Posts: 594
Location: BE
That helped.

But then, with what you said, I thought why wouldn't this work then :
Code:
   Instance\StartMicroSec =  Instance\StartCount * 1000000 / Instance\Frequency
   Instance\StopMicroSec =  Instance\EndCount * 1000000 / Instance\Frequency
And it does too.

Thanks.

_________________
Yeah I know, but keep in mind ... Leonardo da Vinci was also an autodidact.


Top
 Profile  
Reply with quote  
 Post subject: Re: HighResTimer - Module
PostPosted: Mon Aug 08, 2016 8:03 am 
Offline
Enthusiast
Enthusiast

Joined: Fri Oct 16, 2009 10:12 am
Posts: 594
Location: BE
In my search on accurate timings, I also found this site. They talk about a setting in the bios that can change QueryPerformanceFrequency upto 5 times faster.
http://www.neowin.net/forum/topic/1075781-tweak-enable-hpet-in-bios-and-os-for-better-performance-and-fps/

Quote:
By hardbag :
TSC+LAPICs Low performance (slow timers + syncing) = 2.76MHz
LAPICs low performance (slow timer - no syncing) = 3.5Mhz
TSC+HPET medium performance (slow and fast timer + syncing) = 3.8Mhz
HPET high performance (fast timer - no syncing) = 14.3MHz
Run the WinTimerTester 1.1 to see your QueryPerformanceFrequency
Then try with HPET, you'll be amazed.

Reading more comments I'm not going into that (for now). But maybe others can get inspired.

_________________
Yeah I know, but keep in mind ... Leonardo da Vinci was also an autodidact.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 5 posts ] 

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 14 guests


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

Search for:
Jump to:  

 


Powered by phpBB © 2008 phpBB Group
subSilver+ theme by Canver Software, sponsor Sanal Modifiye