GetTickCount on Windows 10
category: code [glöplog]
All of my games developed since 2008 are running (too) slowly on Windows 10. They are using GetTickCount to obtain the system time. Has the behaviour of this method changed in Windows 10?
GetTickCount on Windows 10 has sometimes unusual high values. You know the deal, when casting to float... do always:
And as a side note, never use GetTickCount, the resolution simply sucks. Use Multimedia Timers or High Resolution Timers.
Code:
DWORD start = GetTickCount();
DWORD current = GetTickCount() - start;
And as a side note, never use GetTickCount, the resolution simply sucks. Use Multimedia Timers or High Resolution Timers.
Thanks. I used to cast the tick count to float in my programs. I have now tried what happens when I change that and work with DWORD. The result: It works like a charm.
I will follow your advice and use multimedia timers or high resolution timers in my future programs.
I will follow your advice and use multimedia timers or high resolution timers in my future programs.
General advice: Always use 64bit integers for time values, always diff against some "reference time" liike EvilOne said, and when you like the convenience of using floating point math, convert to double (not float; FPUs are fast enough now) at the last possible moment. And don't mix time bases if possible. An integer low-level time at QPF resolution (or at least microseconds) and a high-level floating point one at 1.0/sec is fine.
Also if you want to handle stuff that comes with their own time base (like audio or video files), consider making the time a fraction consisting of a numerator and denominator - so you can use the LCM of the denominators to find the lowest-res time base that matches all the stuff you're throwing at it.
Also if you want to handle stuff that comes with their own time base (like audio or video files), consider making the time a fraction consisting of a numerator and denominator - so you can use the LCM of the denominators to find the lowest-res time base that matches all the stuff you're throwing at it.
Here's an in-depth article about timers and floating point: https://randomascii.wordpress.com/2012/02/13/dont-store-that-in-a-float/
Note that multimedia timers do not provide a high resolution either unless you set their precision using timeBeginTime to a desired rate.
Reason: A higher resolution increases energy consumption on an otherwise idle cpu, thus potentially decreasing battery running time on mobiles.
There´s another reason for always using relative values with timeGetTime / getTickCount and similar timestamp functions: Their value wraps around after some time, thus computing the delta prior to using the value prevents semi-random unusual high or negative values.
Reason: A higher resolution increases energy consumption on an otherwise idle cpu, thus potentially decreasing battery running time on mobiles.
There´s another reason for always using relative values with timeGetTime / getTickCount and similar timestamp functions: Their value wraps around after some time, thus computing the delta prior to using the value prevents semi-random unusual high or negative values.
Quote:
Note that multimedia timers do not provide a high resolution either unless you set their precision using timeBeginTime to a desired rate.
Reason: A higher resolution increases energy consumption on an otherwise idle cpu, thus potentially decreasing battery running time on mobiles.
Yup, these timers are updated once per timing tick in the OS. Increasing the resolution means decreasing the timeslice of the OS, meaning you get more interrupts/context switches per second.
So QPF/QPC is preferred (it just bugs on some old AMD dualcore CPUs, but there's a software fix for that, with the brilliant name "AMD Dual-Core Optimizer": http://support.amd.com/en-us/search/utilities
Quote:
(it just bugs on some old AMD dualcore CPUs, but there's a software fix for that, with the brilliant name "AMD Dual-Core Optimizer": http://support.amd.com/en-us/search/utilities
Ha, I always wondered what that was about.
I've based my timing code on these two articles:
http://www.geisswerks.com/ryan/FAQS/timing.html (win32 specific)
http://gafferongames.com/game-physics/fix-your-timestep/
.. and last night I realised I think I have a rounding error.. :x
http://www.geisswerks.com/ryan/FAQS/timing.html (win32 specific)
http://gafferongames.com/game-physics/fix-your-timestep/
.. and last night I realised I think I have a rounding error.. :x
+1 for the ryan geiss stuff. You should always do a timeBeginPeriod(1) at the beginning of your program (and timeEndPeriod before exiting), even if you use QPC.
Also: I recall kb once suggesting to query timer values right after calling Present()/swapBuffers() for higher chances of more consistent timesteps..
Also: I recall kb once suggesting to query timer values right after calling Present()/swapBuffers() for higher chances of more consistent timesteps..
funny that, think i call it 3 times.. something like at start/before swapBuffers/ and 'end' after swap and use it to give me a load calculation. think iirc 3 queries are needed if in fps 'capped' mode.. spiinning/sleeping/yielding to save cpu (and hopefully if i get that far battery load)
hopefully i'll read back and remember to verify that i am calling timeEndPeriod.. but then again i'm likely to be breaking out of the debugger a lot of the time. so. i've just double checked, and as with most other windows handles it is cleaned up on process exit, so won't affect the system if your app doesn't clean up.
hopefully i'll read back and remember to verify that i am calling timeEndPeriod.. but then again i'm likely to be breaking out of the debugger a lot of the time. so. i've just double checked, and as with most other windows handles it is cleaned up on process exit, so won't affect the system if your app doesn't clean up.
When you make something where the visuals are synchronized with the sound (such as a demo), don't use an independent timer - use the audio position query of the audio API. That is:
If you use WaveOut, call waveOutGetPosition.
If you use DirectSound, call the GetCurrentPosition method of the IDirectSoundBuffer8 interface.
If you use PlaySound, well, stop doing that. :)
Not only are the position timers of high precision (typically single samples). More importantly, they tell you exactly what you want to know: where in the music am I?
Starting (or querying) a timer when you start the music playback can be quite imprecise, as the sound doesn't necessarily start at exactly the same time as the play function is called (or returns).
If you use WaveOut, call waveOutGetPosition.
If you use DirectSound, call the GetCurrentPosition method of the IDirectSoundBuffer8 interface.
If you use PlaySound, well, stop doing that. :)
Not only are the position timers of high precision (typically single samples). More importantly, they tell you exactly what you want to know: where in the music am I?
Starting (or querying) a timer when you start the music playback can be quite imprecise, as the sound doesn't necessarily start at exactly the same time as the play function is called (or returns).
Quote:
They are using GetTickCount to obtain the system time
Mensa material, clearly.