timeBeginPeriod

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

timeBeginPeriod

Post by deltarho[1859] »

Some of you may know this, but I was a bit slow in catching it.

From Windows 2004 timeBeginPeriod is no longer a global setting.

Applications which do not use timeBeginPeriod will use the default system resolution – 15.625ms.

Applications which do use timeBeginPeriod are subject to the highest resolution requested.

So using a web browser and in particular going to YouTube will no longer affect applications which do not use timeBeginPeriod.

If you write an application and want it to be influenced by a third-party application which changes the timer resolution, then use timeBeginPeriod(16) in your application.

With pre-Windows 2004 if we did not use timeEndPeriod Windows would do it for us on a process closure. This is no longer true - timeBeginPeriod will persist unless we use timeEndPeriod.
sero
Posts: 59
Joined: Mar 06, 2018 13:26
Location: USA

Re: timeBeginPeriod

Post by sero »

deltarho[1859] wrote: Feb 09, 2023 23:51 Applications which do not use timeBeginPeriod will use the default system resolution – 15.625ms.

Applications which do use timeBeginPeriod are subject to the highest resolution requested.
Below is a demonstration implementing timeBeginPeriod for Windows systems. In this demo, the variable sleep_time is set to 16 which should give you roughly 60 frames per second. You can set this value lower as far down as 1 to allow for a higher frame rate. The value can also be set higher for a lower frame rate making timeBeginPeriod an unecessary addition to your code.

Code: Select all

#ifdef __FB_WIN32__
  declare function timer_set alias "timeBeginPeriod" ( _
    as ulong = 1 ) _
    as long
  declare function timer_release alias "timeEndPeriod" ( _
    as ulong = 1 ) _
    as long
#endif

'dim as long sleep_time = 1
dim as long sleep_time = 16

#ifdef __FB_WIN32__
  timer_set()
#endif

dim as double fps_timer, counter_timer
dim as long counter = 0
dim as long fps = 0

screenres 320, 240, 32
fps_timer = timer
do
  counter_timer = timer - fps_timer
  counter += 1
  
  sleep sleep_time
  
  if counter_timer >= 1 then
    fps_timer += 1
    fps = counter
    counter = 0
  endif
  
  screenlock()
    cls
    print "counter: " & counter
    print "    fps: " & fps
  screenunlock()
loop while( inkey = "" )

#ifdef __FB_WIN32__
  timer_release()
#endif
Here is the Microsoft Windows App Development page for timeBeginPeriod:
https://learn.microsoft.com/en-us/windo ... eginperiod

Here is a FreeBasic forums thread giving further explanation on this topic:
viewtopic.php?f=2&t=27371
deltarho[1859]
Posts: 4308
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: timeBeginPeriod

Post by deltarho[1859] »

@sero

I am not sure what point you are trying to make.

Your opening quote is a result of the timeBeginPeriod API you cited, which was edited when Windows 2004 stopped timeBeginPeriod being a global setting.

I was aware of the FreeBASIC forum thread you cited – I contributed to it.

In the opening post, I mentioned using timeBeginPeriod(16). Don't do that because it seems to be treated as if timeBeginPeriod had not been used. Instead, use timeBeginPeriod(15).

For example, using timeBeginPeriod(16) in our application will still use the system default resolution if we go to YouTube. Going to YouTube using timeBeginPeriod(15) in our application will see our application following YouTube's lead.

When Windows 10 was published, I wrote an application called TimerInterval (Win 10) which allowed timer intervals from 0.5ms, 1ms to 15ms, in steps of 1ms, and 15.625ms; much more versatile than timeBeginPeriod. This changed the global setting. It still works, but it no longer sets a global setting, it now becomes simply a process which changes its timer interval. If that interval is less than one of our applications which uses timeBeginPeriod then our application will use it. Any of our other applications which do not use timeBeginPeriod will not be affected as would have been the case pre-Windows 2004.
dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: timeBeginPeriod

Post by dodicat »

I did an example yesterday, but I don't know about deltarho's method, or I must have missed it.
viewtopic.php?p=296794#p296794
What is Windows 2004?
deltarho[1859]
Posts: 4308
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: timeBeginPeriod

Post by deltarho[1859] »

dodicat wrote:I did an example yesterday, but I don't know about deltarho's method, or I must have missed it.
I do the same.

Windows 2004 (Windows 10 May 2020 Update) was codenamed 20H1. According to my 'Settings' I am currently on 22H2.

Microsoft, have an obsession with messing about with versions: XP, Vista, 7, 8, and 8.1. Lately: "Let us not have a version 9." "Erm, you may be right - what shall we use then?" "How about version 10." "Oh, that is a good idea". The hell it was.

"Lets us have 10 as the last." "Splendid idea". Welcome Windows 11 :!:

Guess what? They are now working on Windows 12. :lol:

FreeBASIC is equally barmy. fbc with a beta of 1.10.0 looks like it only started last year. PowerBASIC's Windows compiler is at version 10 which seems like it has been around a while – which it has.
deltarho[1859]
Posts: 4308
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: timeBeginPeriod

Post by deltarho[1859] »

I have another application, written with PowerBASIC, as was TimerInterval (Win10), called TimerInt (Win10) where I can set an interval to something like 12.3456ms. Nobody in their right mind would want that, but I wanted to see if I could do it. I could, but I never use it, preferring TimerInterval (Win10) which sets requested integer intervals. Neither of them set global settings nowadays, of course.
deltarho[1859]
Posts: 4308
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: timeBeginPeriod

Post by deltarho[1859] »

Still on topic.

I first got involved with timeBeginPeriod on Win 7 in 2014.

In those days, with timeBeginPriod(n), we had n = 1, 2, 3, 5, 10, and 16 resulting in intervals of 1ms, 1.25ms, 2.5ms, 5ms, 10ms, and 15.6ms respectively.

This was still the case when Windows 10 was introduced.

However, in 2023 we have n = 1, 2, ..., 16 reulting in 1ms, 2ms, ..., 16ms respectively.

So, Microsoft, when did that happen? :)
sero
Posts: 59
Joined: Mar 06, 2018 13:26
Location: USA

Re: timeBeginPeriod

Post by sero »

deltarho[1859] wrote: Feb 10, 2023 3:12 I am not sure what point you are trying to make.
It was a contribution to your post with brief explanation of an included barebones demonstration as well as a couple links. I think of examples and demonstrations as good things for learning. Linking external information related to the topic is also good for learning. You already know about these things, but others may not. If you're looking for a point this is it.
deltarho[1859] wrote: Feb 10, 2023 3:12 Your opening quote is a result of the timeBeginPeriod API you cited, which was edited when Windows 2004 stopped timeBeginPeriod being a global setting.
Yup, this justifies a reason for providing an example of implementation for interested coders who don't know about this to get started. This is why I set a sleep value to 16 in my code to create a control environment from which users can experiment with changing this value and more clearly understand the resulting behavior through comparison. I described outcomes to look for in my response.
deltarho[1859] wrote: Feb 10, 2023 3:12 I was aware of the FreeBASIC forum thread you cited – I contributed to it.
Yes, I was fully aware. My response was not meant solely for you but anyone who comes across this thread. That's why I provided the links. I appreciate dodicat's response including an additional link relating this thread to that one.
deltarho[1859] wrote: Feb 10, 2023 3:12 In the opening post, I mentioned using timeBeginPeriod(16). Don't do that because it seems to be treated as if timeBeginPeriod had not been used. Instead, use timeBeginPeriod(15).
Agreed. I never mentioned changing the timeBeginPeriod(x) value. My demonstration code provided a variable for the sleep duration, not for timeBeginPeriod(x). In my demonstration I left timeBeginPeriod to its default value of 1. My example code revealed this default value to any reader within the first few lines within the function declaration.
deltarho[1859] wrote: Feb 10, 2023 3:12 For example, using timeBeginPeriod(16) in our application will still use the system default resolution if we go to YouTube. Going to YouTube using timeBeginPeriod(15) in our application will see our application following YouTube's lead.
Yes of course. I provided a barebones demonstration on implementing the use of timeBeginPeriod so that others who don't already know have an example from which to get started without the need to search for one. My response described outcomes of lowering and raising the sleep value within my demonstration. In my code I included a commented out line where my variable sleep_time was set to 1 to encourage users to try other values which I also touched on in my response.
deltarho[1859] wrote: Feb 10, 2023 3:12 When Windows 10 was published, I wrote an application called TimerInterval (Win 10) which allowed timer intervals from 0.5ms, 1ms to 15ms, in steps of 1ms, and 15.625ms; much more versatile than timeBeginPeriod. This changed the global setting. It still works, but it no longer sets a global setting, it now becomes simply a process which changes its timer interval. If that interval is less than one of our applications which uses timeBeginPeriod then our application will use it. Any of our other applications which do not use timeBeginPeriod will not be affected as would have been the case pre-Windows 2004.
I'm glad you started this thread after discovering the updated change in Windows. This is one of many reasons why I appreciate the FreeBasic community.
deltarho[1859]
Posts: 4308
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: timeBeginPeriod

Post by deltarho[1859] »

Good post, sero - I fully endorse your comments.

If ever you read any of my PRNG posts, you will know that I 'go to town' on explaining things and always include an 'Example usage' section.

I can imagine some members saying: “Ah, deltarho has posted yet another PRNG implementation – I had better put the kettle on – I may be gone sometime.” :lol:

This thread was never intended as a tutorial, but more of a 'For your information' (FYI) thread. So, an explanation of timeBeginPeriod was beyond its scope. Of course, I could have said that as an opening statement. In future with a FYI thread I will do just that.

:wink:
adeyblue
Posts: 300
Joined: Nov 07, 2019 20:08

Re: timeBeginPeriod

Post by adeyblue »

The decades of madness of timeBeginPeriod + science
https://randomascii.wordpress.com/2020/ ... le-change/
deltarho[1859]
Posts: 4308
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: timeBeginPeriod

Post by deltarho[1859] »

I have read adeyblue's link several times now, but do not fully understand it.

My conclusion may be wrong then, but it seems to me that the issues raised will be of no concern to the majority, if not all, of forum members using timeBeginPeriod.

I am fairly confident that the new protocol is not whether timeBeginPeriod is used or not, but whether NtSetTimerResolution is used or not. If we use timeBeginPeriod, then we will be using NtSetTimerResolution. Obviously, MSDN cannot mention NtSetTimerResolution in the timeBeginPeriod documentation.

If we have two instances of my 'TimerInterval (Win 10)' with the first instance setting an interval of 10ms and the second instance setting an interval of 5ms, then both instances will report 5ms; assuming that 5ms is the lowest value requested by any process.'TimerInterval (Win 10)' uses NtSetTimerResolution and not timeBeginPeriod.

'TimerInterval (Win 10)' does the same job as 'Windows System Timer Tool' and TimerResolution mentioned in adeyblue's link, and is equally broken. By that, I mean none of them set a global interval because we cannot do that any more. They will only affect other processes using NtSetTimerResolution.

The reason for using NtSetTimerResolution is that it gave us access to intervals of 0.5ms, 1ms to 16ms, with a 100ns granularity, whereas timeBeginPeriod only gave us access to 1, 2, 3, 5, 10, and 16. I'm guessing, but I reckon that the extended timeBeginPeriod came in with the Windows 10 May 2020 Update. In practice, NtSetTimerResolution is now only useful for an interval of 0.5ms to 1ms, with a 100ns granularity, if their system allows it. I doubt that anyone would want less than 1ms. Mozilla Firefox uses timeBeginPeriod/timeEndPeriod. I may be wrong, but I reckon at one time they used NtSetTimerResolution. They are using other Ntxx functions.

As a matter of interest, Linux uses 10ms for its system default interval. How do we change that – I have no idea?
deltarho[1859]
Posts: 4308
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: timeBeginPeriod

Post by deltarho[1859] »

Regarding Windows 11 and the two instances of 'TimerInterval (Win 10)' in the last post, then minimizing the second instance will see the interval change to 10ms; the interval requested by the first instance. The second instance will now be using the default system interval.

I cannot test that.

I don't know about the setting applications mentioned in adeyblue's link, but when 'TimerInterval (Win 10)' is minimized, it stops monitoring and resumes when restored. With Windows 11, it will stop setting as well.

Microsoft's logic here evades me.

I wonder what the author of adeyblue's link would say about that. :)

Added: Both of the setting applications mentioned in adeyblue's link can be minimized, rendering them useless when minimized in Windows 11. Is Microsoft on the attack here? No, they wouldn't do that, would they? :)
sero
Posts: 59
Joined: Mar 06, 2018 13:26
Location: USA

Re: timeBeginPeriod

Post by sero »

I'm sorry @deltarho I don't have an answer. I feel your frustration.

I noticed a similar thread recently in the PowerBASIC forum https://forum.powerbasic.com/forum/user ... eginperiod. I hope someone can provide you an answer.

I was surprised to read that Linux uses 10ms for its default. I was under the impression that Linux schedules each application according to its demand as low as 1ms. I only work in Windows so I'm not surprised I was wrong about this. Linux has always been beyond my comfort zone despite my modest efforts with Ubuntu in the past.
deltarho[1859]
Posts: 4308
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: timeBeginPeriod

Post by deltarho[1859] »

sero wrote:I noticed a similar thread recently in the PowerBASIC forum
So did I, but it was easier for me because I started it. :) I joined the PB forum in 2003. I don't go there much nowadays, but I could not miss them out on the latest timeBeginPeriod 'shake up'. It appears that nobody knew about it.

I should not think that the following will be an issue, but I will mention it anyway. If a parent process executes a child process and changes the timer resolution such that it is the smallest interval requested by any process, then the old protocol will see the child process adopt the same resolution. With the new protocol, the child process will use the system default if it does not use timeBeginPeriod. It was this issue that got the author of adeyblue's link to investigate.

If we write the child process and need to use the same resolution as the parent, one way would be to add timeBeginPeriod(15) to it. The child process will now adopt the resolution used by the parent; whatever that is. We don't need to specify the same resolution as the parent. Change the parent resolution and the child will follow.

We must remember to use timeEndPeriod(15) before exiting the child process.

It is not a frustration for me. The MSDN documentation has to be one of the most poorly written APIs since it was introduced in Windows 2000 Professional. The truth is, Microsoft would rather have nobody use it.

Before Windows 10 we had to follow tImeBeginPeriod(1) with 'Sleep 16' because it took two ticks for it to 'bite'. Microsoft never got around to telling us that. :)
deltarho[1859]
Posts: 4308
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: timeBeginPeriod

Post by deltarho[1859] »

I have just read a comment suggesting timeSetEvent should be preceded with timeBeginPeriod to give timeSetEvent a higher resolution. Do you do that?

There is no need as timeSetEvent supposedly uses timeBeginPeriod internally – that is what timeSetEvent's second parameter, uResolution, is for. I don't believe that timeBeginPeriod is used internally but NtSetTimerResolution is, which has a granularity of 100ns. 'timeEndPeriod' is invoked on a timer completion.
Post Reply