pouët.net

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?
added on the 2016-08-03 12:43:56 by Adok Adok
GetTickCount on Windows 10 has sometimes unusual high values. You know the deal, when casting to float... do always:
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.
added on the 2016-08-03 13:39:18 by EvilOne EvilOne
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.
added on the 2016-08-03 14:01:18 by Adok Adok
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.
added on the 2016-08-03 15:11:52 by kb_ kb_
Here's an in-depth article about timers and floating point: https://randomascii.wordpress.com/2012/02/13/dont-store-that-in-a-float/
added on the 2016-08-03 21:55:58 by absence absence
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.
added on the 2016-08-04 02:21:18 by T$ T$
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
added on the 2016-08-04 09:18:12 by Scali Scali
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.
added on the 2016-08-04 12:25:30 by sol_hsa sol_hsa
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
added on the 2016-08-04 12:59:45 by Canopy Canopy
+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..
added on the 2016-08-04 18:14:13 by arm1n arm1n
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.
added on the 2016-08-04 18:36:31 by Canopy Canopy
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).
added on the 2016-08-13 10:02:23 by Blueberry Blueberry
Quote:
They are using GetTickCount to obtain the system time


Mensa material, clearly.
added on the 2016-08-14 04:52:58 by superplek superplek

login