timeBeginPeriod without matching timeEndPeriod

At line 970-971 in the source code (of day 24), it says

UINT DesiredSchedulerMS = 1;
bool32 SleepIsGranular = (timeBeginPeriod(DesiredSchedulerMS) == TIMERR_NOERROR);

According to the MSDN documentation for the timeBeginPeriod call (http://msdn.microsoft.com/en-us/l...esktop/dd757624%28v=vs.85%29.aspx):

"You must match each call to timeBeginPeriod with a call to timeEndPeriod, specifying the same minimum resolution in both calls. An application can make multiple timeBeginPeriod calls as long as each call is matched with a call to timeEndPeriod."

However, I cannot see that timeEndPeriod is called anywhere in the source?
he is not a big fan of unnecessary cleanups, during one of his streams he talked about allowing the os to do the cleaning on exit, and that its up to you to decide what you want to dispose of, i normally do the cleaning manually, feels ikky if i dont.
We do not ever want to close the period, because we are trying to keep the scheduler at 1ms for the duration of the application.

We could call it at the very end, before the app closes, but I don't actually know if that would have any actual effect.

- Casey
Yeah, since timeBeginPeriod was called at the very beginning of execution, it was implied that the corresponding timeEndPeriod should be called at the very end - if at all - but I wasn't sure whether it was redundant or not, like if Windows automatically "wraps it up" / does it for you at the termination of the process or something (since it's not a resource, but rather a global Windows thing*).

*"This function affects a global Windows setting. Windows uses the lowest value (that is, highest resolution) requested by any process. Setting a higher resolution can improve the accuracy of time-out intervals in wait functions. However, it can also reduce overall system performance, because the thread scheduler switches tasks more often. High resolutions can also prevent the CPU power management system from entering power-saving modes. Setting a higher resolution does not improve the accuracy of the high-resolution performance counter."

Edited by d7samurai on
Turns out that the raised timer frequency is indeed automatically cancelled by Windows when the process terminates. So nevermind *that* point, but anyway:

https://randomascii.wordpress.com...imer-resolution-megawatts-wasted/

"When a process calls timeBeginPeriod this frequency request is in force until it is explicitly cancelled with timeEndPeriod or until the process terminates. Most programs (including my own test program below) never call timeEndPeriod, relying instead on Windows process cleanup. This works, and is reasonable for any application that needs the timer frequency high for its entire lifetime, but for any process whose lifetime may outlast its need for a high frequency timer, it’s time to start calling timeEndPeriod. As Microsoft recommends, this includes movie players that are paused, and games that are minimized. It also includes web browsers that do not currently need high-resolution timers, or are running on battery power."

Edited by d7samurai on
after reading the documentation more closely, it might be a good idea to call timeEndPeriod on WM_ACTIVATE, SC_MINIMIZE and SC_SCREENSAVE, the article you linked to mentioned that it can effect battery power by almost 25%

also we should call timeGetDevCaps to query the lowest possible value the system is capable of, instead of hard coding it to 1

is there any plans in the future to dynamically switch back and forth between the 33ms wall clock we currently have, and the windows message pump when we go into idle mode ?

Edited by ambiguous panda on
When window looses focus you could do even better - pause rendering, stop calling GameUpdateAndRender and most importantly change PeekMessage to GetMessage. This way application will consume least possible CPU time.
we can still render on WM_PAINT and a longer wall clock during idle, so you cant cheat by pausing the game with alt-tab

this is kinda off-topic, and probably wont even be a thing for another month or so. :(

Edited by ambiguous panda on
I can confirm that this is not a "useless cleanup". This needs to be called before your process ends.

I both tested this in another project of mine and there's a huge writeup of the effects here: https://randomascii.wordpress.com...imer-resolution-megawatts-wasted/

I just want to highlight this sentence
“Some applications reduce this to 1 ms, which reduces the battery run time on mobile systems by as much as 25 percent.”

edit: nevermind, that already got posted, but I can't delete my post :(

edit2: weird, tested again, it does seem to reset on my current system.

Edited by Bigpet on
a good alternative is

SetWaitableTimerEx function

lpDueTime [in]

The time after which the state of the timer is to be set to signaled, in 100 nanosecond intervals.
AFAIK, timeBeginPeriod affects the granularity of ::Sleep(). I'm only at day 19 right now so this premise may not hold very long.

Will there more than one call to ::Sleep?

If there is only one call than it can be bracketed by begin-end period calls. This would avoid dealing with losing focus, etc.

I'm not sure how a 1 ms timerbeginPeriod affects thread behavior, though.

- tim
RomulusTFM
AFAIK, timeBeginPeriod affects the granularity of ::Sleep(). I'm only at day 19 right now so this premise may not hold very long.

Will there more than one call to ::Sleep?

If there is only one call than it can be bracketed by begin-end period calls. This would avoid dealing with losing focus, etc.

I'm not sure how a 1 ms timerbeginPeriod affects thread behavior, though.

- tim

There is one call to Sleep *per frame*. We don't want to be setting and unsetting the timer resolution every frame. So we set it once before our main loop and leave it alone until the process ends.
Right. There is also a MS note someplace saying that you should not keep changing it.

- tim