You are not logged in. You can browse in the PowerBASIC Community, but you must click Login (top right) before you can post. If this is your first visit, check out the FAQ or Sign Up.
In another thread party pooper Paul Dixon had the audacity to question the accuracy of my macro timers. I agree with him. The granularity of the Performance Counter is inadequate for very small timings using a Counter frequency of 14,318,180. The situation is worse with a frequency of 10MHz, the default for Windows 10.
To err on the side of caution I am recommending that TIX be used if my macro timers return a time of less than five microseconds.
It is worth noting that with a PCF of 10MHz, with Windows 10, giving a resolution of 100 nano-seconds, that is one-tenth of a micro-second, then using 6 or 7 in sTimeTaken's second parameter will not work - one decimal place will be as good as it gets.
If we enable HPET in the bios and run 'bcdedit /set useplatformclock true' (and reboot) in admin mode command prompt then the PCF increases to 14,318,180, which is what I used with Win7, and now we will get more than one decimal place with 6 or 7 in sTimeTaken's second parameter.
I find it bizarre when we disable HPET in the bios but keep the above command prompt to find we get a PCF of 3,579,545 which is the same frequency as the crystal used for NTSC colour TVs.
If we now run 'bcdedit /deletevalue useplatformclock' (and reboot) we get the 10MHz back.
The jury was always 'out' on whether to enable the HPET and since it is old technology I would rather steer clear of it so I use a PCF of 10MHz. I really do not need to go beyond one decimal place in micro-second timing.
I am not sure how Microsoft manages to provide a PCF of exactly 10MHz. Both Microsoft and Intel have done some clever stuff in recent years, the Time Stamp Counter is now invariant - that is the same for all cores.
In view of recent posts, I thought that it may be a good idea to resurrect my timer macros. However, the latest version, published some time ago, is probably much more powerful than most people's needs so below is a stripped down version.
Essentially we may use up to 16 timers, 0 to15.
The Performance Counter is used. In the 'old days,' the frequency varied, slightly, between Windows sessions but that is no longer the case with modern systems. On Windows 10 the frequency is 10MHz giving then a resolution of 100 nano-seconds.
MultipleTimersLite.inc
Code:
Global qFreq, qStart(), qStop() As Quad
Global sFuncName() As String
Macro InitializeTimers
Dim qStart( 0 To 15) As Global Quad
Dim qStop( 0 To 15 ) As Global Quad
Dim sFuncName( 0 To 15 ) As Global String
QueryPerformanceFrequency qFreq
QueryPerformanceCounter qStart(0) ' Intel suggestion. First use may be suspect
Reset qStart(0)
End Macro
Macro sPCF = LTrim$(Format$(qFreq, "###,###,###,###"))
' Starting & Stopping timers
' ********************
Macro StartTimer(i)
sFuncName(i) = FuncName$
QueryPerformanceCounter qStart(i)
End Macro
Macro StopTimer(i) = QueryPerformanceCounter qStop(i)
' ********************
' Display
' In the following
' i is the ith timer
' 0 <= j <= 3 for 0 to 3 decimal places in ms
' 4 <= j <= 7 for 0 to 3 decimal places in µs
' If j > 7 then j is clipped To 7
' flag = 0 => non-verbose output in ms or µs only
' flag = 1 => verbose output including Timer index and Function name
' ********************
Macro Function sTimeTaken( i, j, flag )
MacroTemp s, k
Local s As String, k As Long
k = Min&(Abs(j),7)
s = Choose$(k+4*(k>3)+1, "####", "####.#", "####.##","####.###")
s = " " + Format$((qStop(i) - qStart(i))*IIf&(k<4, 1000, 1000000)/qFreq, s) + IIf$(k<4, "ms", "µs")
If IsTrue flag Then
s = "[" + LTrim$(Str$(i)) + "] in " + sFuncName(i) + s
End If
Reset qStart(i)
End Macro = s
Macro Function nTimeTaken(i)
MacroTemp n
Local n As Double
n = (qStop(i) - qStart(i))*1000/qFreq
Reset qStart(i)
End Macro = n
' ********************
Example usage:
Code:
#Compile Exe
#Dim All
#Include "win32api.inc"
#Include "C:\PBWin\Timers\MultipleTimersLite.inc" ' Change to your path
Function PBMain () As Long
Local x As Double
Local i As Long
InitializeTimers ' We must not forget this
Test
? sTimeTaken(0,1,0)
' Waitkey$
End Function
Sub Test
Local i As Long
Local x As Double
StartTimer(0)
For i = 1 To 20000000
x = Rnd
Next
StopTimer(0)
End Sub
Notes:
With regard sTimeTaken: The first parameter is the timer index; the second parameter is 0 to 3 for 0 to 3 decimal places in milli-seconds and 4 to 7 for 0 to 3 decimal places in micro-seconds; the third parameter is 0 for non-verbose output and 1 for verbose output which includes the timer index and Function name.
For non-verbose sTimeTaken(0,1,1) will look like this 241.7ms and in verbose will look like this [0] in TEST 241.7ms
nTimeTaken(0) would give simply 241.6547 as a Double.
sPCF gives, as a string, the Performance Counter Frequency. On Windows 10 that is 10,000,000.
Last edited by David Roberts; 18 Mar 2019, 02:21 PM.
We process personal data about users of our site, through the use of cookies and other technologies, to deliver our services, and to analyze site activity. For additional details, refer to our Privacy Policy.
By clicking "I AGREE" below, you agree to our Privacy Policy and our personal data processing and cookie practices as described therein. You also acknowledge that this forum may be hosted outside your country and you consent to the collection, storage, and processing of your data in the country where this forum is hosted.
Leave a comment: