timeBeginPeriod

Windows specific questions.
deltarho[1859]
Posts: 4305
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: timeBeginPeriod

Post by deltarho[1859] »

It is worth noting that your output of post #4 will differ to mine if your Performance Counter's frequency is 10MHz the Windows 10 default. When I did the test my frequency was at 14318180Hz.

Using 10MHz I get:
Image

I have no justification for using 14318180Hz. I used that with Windows 7. Microsoft didn't set the frequency at10MHz with Windows 10 for the fun of it. They probably take the view that incrementing at 10MHz is more efficient than 14318180Hz. 10MHz gives a resolution of 100ns which, let's face it, should be good enough for most of us.The analogy is increasing the default timer resolution for long periods – reducing overall system performance.

So, I am back to 10MHz. :)
deltarho[1859]
Posts: 4305
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: timeBeginPeriod

Post by deltarho[1859] »

I have just updated MacroTmersQPC.inc in the 'Sources, Examples, Tips and Tricks' forum. The new version is called MultipleTimers.inc. Read the update to see why.

Had MultipleTimers.inc been used in post #4 then I could have simply used this:

Code: Select all

'#console on

#include Once "I:\FreeBASIC\MacroTimers\MultipleTimers.inc" 

Print "Performance counter frequency: ";liFreq
Print

' Usage example:
For i As ULong = 1 to 20 ' Milliseconds
  StartTimer(0)
  VeryHiResSleep( i )
  StopTimer(0)
  Print i;Tab(6);nTimeTaken(0)
Next

Sleep

deltarho[1859]
Posts: 4305
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: timeBeginPeriod

Post by deltarho[1859] »

@dodicat

Just out of interest, I had a look at your GetSystemTimePreciseAsFileTime post.

I did a small rewrite because GetSystemTimePreciseAsFileTime is in "Winbase.bi" and used the VeryHiResSleep(1) macro. Oh, I changed your Sleep 1 to Sleep 1,1. I went past the sleep 20 times.

Code: Select all

'#console on
#inclib "winmm"
#include Once "I:\FreeBASIC\MacroTimers\MultipleTimers.inc" ' New vesion of MacroTimersQPC.inc
 
Function Ftick64() As Ulongint
      Dim As FILETIME f=Any
      Dim As Ulongint flow=Any,fhigh=Any,mytime=Any
      GetSystemTimePreciseAsFileTime(@f)
      fLow  = f.dwLowDateTime
      fHigh = f.dwHighDateTime
      myTime = fLow Or (fHigh Shl 32)
      Return myTime
End Function
 
Sleep 50
Dim As String s
dim as ulongint t
For n As Long=1 To 20
       t=Ftick64
      VeryHiResSleep(1)
      s+=Str((Ftick64-t)\10)+!" microseconds\n"
Next
Print s
Sleep

The left image is your code output, with mine on the right.
Image

I thought I had read that GetSystemTimePreciseAsFileTime was broken, but it seems to be doing OK. I actually use it in an application, without issue, I wrote to correct my system clock every couple of hours, querying Stratum 2 time-servers in the US.

Perhaps I should have called my VeryHiResSleep GetSleepTimePreciseAsFileTime. :)
deltarho[1859]
Posts: 4305
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: timeBeginPeriod

Post by deltarho[1859] »

At here dodicat and I get 64 FPS using 'Sleep 1'. Using settimer and freetimer dodicat gets 445 FPS and I get 500 FPS.

If I use VeryHiResSleep(1) I get 940 FPS.

That is motoring. :)
deltarho[1859]
Posts: 4305
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: timeBeginPeriod

Post by deltarho[1859] »

This was not intended, but with VeryHiResSleep(n) n need not be integral.

Using VeryHiResSleep(0.5) in my last post I get 1838 FPS.

With the post before that, I get 500 microseconds.

:)
deltarho[1859]
Posts: 4305
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: timeBeginPeriod

Post by deltarho[1859] »

I asked ChatGPT why Windows 10 default performance counter frequency is set to 10MHz.

It came up with this.
"The value of 10 million for the performance counter frequency was chosen because it provides a good balance between accuracy and performance. A higher frequency would provide more accuracy but at the cost of increased overhead, while a lower frequency would reduce overhead but at the cost of reduced accuracy.

It's worth noting that the performance counter frequency can be adjusted by applications if needed, but it is generally recommended to use the default value unless there is a specific reason to change it."

I figured that.

I have done quite a few tests comparing 10MHz with 14318180Hz and there is a system performance hit using the latter. It isn't much, but is a hit nonetheless.
srvaldez
Posts: 3379
Joined: Sep 25, 2005 21:54

Re: timeBeginPeriod

Post by srvaldez »

what would happen if instead of 10 million you set it to 1 million
deltarho[1859]
Posts: 4305
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: timeBeginPeriod

Post by deltarho[1859] »

To get 14318180Hz:

At the command prompt, in admin mode, execute 'bcdedit /set useplatformclock true' then Restart and enable HPET in the BIOS; if you can. This is the High Precision Event Timer [1]

To return to 10Mhz:

At the command prompt, in admin mode, execute 'bcdedit /deletevalue useplatformclock' then Restart and disable HPET in the BIOS; if you can. [2]

However, if we use 'bcdedit /set useplatformclock true' and disable HPET in the BIOS we get a frequency of 3579545Hz which is the same frequency as the crystal used for NTSC colour TVs. This is the ACPI timer. [3]

If we now use 'bcdedit /deletevalue useplatformclock' and enable HPET in the BIOS we get 10MHz. HPET has not been enabled in Windows. [4]

So with [2] and [4] it doesn't matter whether HPET is enabled or not in the BIOS – it is not enabled in Windows.

My understanding is that the performance counter frequency is a blend, besides [3], of the Time Stamp Counter and the ACPI timer.

Windows controls the blend and that is how it can achieve 10MHz.

We cannot control the blend and from the above we can only have 3579545Hz, 10000000Hz, or 14318180Hz on Windows 10.

So to answer your question srvaldez: "what would happen if instead of 10 million you set it to 1 million"

From our perspective, there is no answer because we cannot set the frequency to 1 million.

We could get a system performance boost by using 3579545Hz, but I don't know how that would affect our system besides a reduction in accuracy. I certainly will not run my machine for long periods at 3579545Hz to find out. :)

3579545Hz gives a resolution of 279.365ns compared with the default of 100ns. If we check out the APIs at MSDN we find 100ns cropping up all over the place and perhaps why 10MHz was chosen and not less.
Last edited by deltarho[1859] on Feb 22, 2023 10:47, edited 1 time in total.
deltarho[1859]
Posts: 4305
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: timeBeginPeriod

Post by deltarho[1859] »

The above post was edited to give a bit more clarity.

It appears that we can disable HPET via 'Device Manager>System devices>High Precision Event Timer' rather than the BIOS. However, once disabled, we cannot enable it via Device Manager - the entry isn't there. :o
srvaldez
Posts: 3379
Joined: Sep 25, 2005 21:54

Re: timeBeginPeriod

Post by srvaldez »

thank you deltarho[1859] for he detailed explanation :)
deltarho[1859]
Posts: 4305
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: timeBeginPeriod

Post by deltarho[1859] »

Yours truly wrote:we cannot enable it via Device Manager - the entry isn't there. :o
Yes, that surprised me.

So I tried this:

With HPET enabled in the BIOS instead of 'bcdedit /deletevalue useplatformclock' which gives a performance counter frequency of 10MHz, from above, we use 'bcdedit /set useplatformclock false' we still get a performance counter frequency of 10MHz.

However, we can now enable HPET in Device Manager instead of in the BIOS.

Image

The entry is not in Device Manager when we use /deletevalue - that restores defaults, apparently. Using false disables.

I cannot find anyone mentioning the ability to enable via Device Manager. I first looked at this subject 12 years at PowerBASIC and have always used /deletevalue because everyone else did.

As with timeBeginPeriod we do not get the full story from Microsoft. I wonder whether Microsoft sometimes reckons there are some things which we don't need to know, or they make a policy decision not to tell us some things. The 10MHz, for example. We are not told how this done or why. "My understanding is that the performance counter frequency is a blend, besides [3], of the Time Stamp Counter and the ACPI timer." I have seen two sources say that, but no citation was given and they were not Microsoft employees.

This thread is longer than I thought it would be.

Conclusion: With timeBeginPeriod get in and out as quick as possible – which is what VeryHiResSleep does. With Windows 10 and the Performance Counter, leave well alone and stay with 10MHz.

:)
deltarho[1859]
Posts: 4305
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: timeBeginPeriod

Post by deltarho[1859] »

I have just read some clown saying the Windows 10 10MHz isn't really 10MHz and it is a bug.

10MHz was introduced in Windows 10 version 1809 (Windows 10 October 2018 Update) – that is more than four years ago.

If we read the performance counter (TimeNow) then given the correct frequency we can determine what the performance counter will be in, say, five seconds time (Target).

We can poll the counter until we exceed Target. If we use GetTickCount before and after the loop, we can get how long the loop took.

Code: Select all

#include Once "I:\FreeBASIC\MacroTimers\MultipleTimers.inc"
 
Print "Performance counter frequency: ";liFreq
Print
 
Dim As ULongInt Target, TimeNow, GTC0, GTC1
QueryPerformanceCounter Cast( Large_Integer Ptr, @TimeNow )
Target = TimeNow + 5000*liFreq/1000 ' 5 seconds into the future
GTC0 = GetTickCount
Do
  QueryPerformanceCounter Cast( Large_Integer Ptr, @TimeNow )
Loop Until TimeNow >= Target
GTC1 = GetTickCount
Print GTC1 - GTC0
 
Sleep
I get 5000 milliseconds which, in my book, is five seconds. :)
deltarho[1859]
Posts: 4305
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: timeBeginPeriod

Post by deltarho[1859] »

Found an article where the author was not a happy sausage about 10MHz – causing performance loss/increased jitter/latency. He also mentioned an elevated DPC latency.

I don't do any audio/video work.

Anyway, I ran the free vesrsion of LatencyMon ( If you click on the link it will start downloading ) and it came back with:

Image
My system is about nine years old.

So, I do not need to 'up the ante' on 10MHz. :)
deltarho[1859]
Posts: 4305
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: timeBeginPeriod

Post by deltarho[1859] »

I have been looking for an example to push VeryHiResSleep to breaking point and found one - '2D Parallax Scrollng Example' by UEZ.

Here is a zipped folder (706KiB) containing Parallax1.exe. Parallax2.exe, and an Image folder. Windows will moan, but ignore that.

Parallax1 is UEZ's code as is using dodicat's Regulate function. I tried to squeeze more fps couldn't get more than 60. Parallax2 removes Regulate and replaces it with VeryHiResSleep(n).

n is below the 'Sleep/Performance counter' threshold, so the counter dominates. Parallax1 uses up to 5% CPU usage. Parallax2 goes up to about 16%. That is hefty, and one of my cores was close to maxing out. My CPU idles at about 39ºC, but shot up to about 56ºC with Parallax2. I get that when my system backup is working.

An interesting exercise. I am not suggesting for one minute that Regulate be replaced. It has served this forum well. VeryHiResSleep is simply another piece of kit which could have a role in other programs.

The value of n? I did say push to the limit. A lot less than 1 millisecond – 50 microseconds. :)

Added: Of course, one aspect of this test shows how blindingly fast FreeBASIC is.
Post Reply