On 03/31/2012 12:47 AM, Victor Stinner wrote:
Can you go into more detail about QPC()'s issues?
Yes, see the PEP:
http://www.python.org/dev/peps/pep-0418/#windows-queryperformancecounter

FYI, Victor, the PEP is slightly incomplete. Not that this is your fault--you've done your homework. But I've actually lived through it. I was a professional Win32 developer for 15 years, and I attempted to write a game on Windows back in the early-mid 2000s.

On Windows XP, QPC /usually/ uses the ACPI timer in my experience, but sometimes uses RDTSC. Both of these had troubles.

With TSC, there's the clock skew between the two cores that they claim was fixed in SP2. (You could also sidestep this problem by setting core affinity to the same core for all your threads that were going to examine the time.) But there's another problem: the TSC frequency actually *does* change when SpeedStep kicks in. I know someone who complained bitterly about running Half-Life 2 on their shiny new laptop, and when it'd overheat SpeedStep would knock down the processor speed and the game's logic update rate would drop in half and now Gordon was running through molasses.

With the ACPI timer, that's where you saw the leap-forwards-by-several-seconds-under-heavy-load problem (the cited MSKB article KB274323). That only happened with a specific south bridge chipset, which was Pentium-III-only. I never heard about anyone experiencing that problem--personally I had good experiences with that timer. The downside of the ACPI timer is that it's slow to read; it took just over a microsecond in my experiments. (timeGetTime was 20x faster. I don't know how long GetTickCount takes.)

The documentation warnings about timeBeginPeriod is ancient, like Windows 95 era. On any computer running Python 3.3, you can safely call timeBeginPeriod(1) with confidence that you'll get consistent 1ms resolution. Likewise with calling into winmm--it shipped with every OS 3.3 supports. It's just not a big deal and you don't need to mention it in the PEP.

I had a hypothetical idea for a hybrid software clock for games that would poll all possible sources of time (RDTSC, QPC, GetTickCount, timeGetTime) and do its level best to create a high-quality synthetic time. Like, if QPC jumped forward by a huge amount, and that jump wasn't corroborated by the other time functions, it'd throw that delta away completely. It'd also notice if QPC's frequency had changed due to SpeedStep and recalibrate. And it'd handle rollover of timeGetTime(). Of course, part of the problem is that calling all these clocks is slow. Another is that if QPC is implemented using RDTSC and RDTSC has problems you're kind of out of options--your best clock at that point only has 1ms accuracy. Anyway I never wound up getting this to work--my attempts were all full of nasty heuristics and the code turned into hash. Maybe someone smarter than me could figure out how to get it to work.

Sorry that this is incomplete / dashed off, but I'm still on vacation and it's been a few years since I did Windows timing stuff. And I gotta go to bed--going to Madurodam in the morning!


//arry/
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com

Reply via email to