Zitat: |
Habe nun, ach! [...] leider auch Win32-APIs [1]
Durchaus studiert, mit heißem Bemühn.
Da steh ich nun, ich armer Tor!
Und bin so klug als wie zuvor; |
Nunja, nicht ganz.
Nummer 1: eine einfach aufsteigende Zeitquelle neben QPC gibt es nicht. Alle Zeit
geber versuchen sich mehr oder weniger erfolgreich an Absolutzeiten
[2].
Nummer 2: eine bestimmte Zeitspanne
abwarten ist ein viel häufigeres Problem - und wird ganz zurecht damit abgebügelt dass das auf einem nicht-realtime-Kernel nicht geht.
Nummer 3: die in #1 erwähnten Geber sind granular.
Versuchsaufbau: Abwarten einer gewissen Zeit und Aufschreiben der Messwertdifferenz.
Erwarten würden wir sowas in der Art:
Abb. 1: QueryPerformanceCounter() Rot: Messwertdifferenz(us) über Sleep-Zeit(ms), Blau: Erwartungswert us=1000ms
Jeder Messwert ist leicht über dem Erwartungswert. Passt so, da Sleep immer kurz nach der eingestellten Zeit zurückkehrt. Bei der kurzen Zeit ist das wirklich so messbar.
Gleiches Experiment mit SysUtils.Now, welches Kernel32.GetLocalTime aufruft. Das fragt den gleichen Timer ab wie GetSystemTimeAsFileTime (kann man sich fast aus dem Namen denken), und dieser wird wie auch von
Tranx festgestellt nur alle 15.625ms (1/64 Sekunde)
[3] aktualisiert.
Abb. 2: Now() Rot: Messwertdifferenz(us) über Sleep-Zeit(ms), Grün: Erwartungswert us=1000ms
Also, ab zu MMSystem's timeGetTime: diese liest einen Timer, der je nach Systemeinstellung einen anderen Teiler haben kann als 64, bis runter auf 1/1000s.
Spannenderweise ist das auf meinem System schon fast auf die minimale Auflösung von 1ms eingestellt, wie an Abb 3 und 4 zu erkennen ist:
Abb. 3: timeGetTime, Standardeinstellungen Rot: Messwertdifferenz(ms) über Sleep-Zeit(ms), Grün: Erwartungswert
Abb. 4: timeGetTime, 1ms angefordert Rot: Messwertdifferenz(ms) über Sleep-Zeit(ms), Grün: Erwartungswert us=ms
Auffällig an Abb.4 ist auch, dass die 1ms wirklich erreicht wird - die "Sprünge", die man dort erkennt sind wirklich 1ms-Stufen, die zu Rauschen in dieser Größe passen. In Abb.3 ist das alles etwas verstreuter, die Statistik dazu überlass ich mal dem Leser als Hausaufgabe. Die Rohdaten sind auf Anfrage verfügbar
Die zwei Alternativen sind also: QPC und hohe CPU-Last in Kauf nehmen oder timeGetTime und etwas Genauigkeit aufgeben. 1ms ist ja auch ganz nett.
So, und jetzt les ich
[3] erstmal komplett...
Referenzen:
[1]
stackoverflow.com/qu...imestamps-on-windows
[2]
www.lochan.org/2005/...seful/win32time.html
[3]
www.windowstimestamp.com/description#C_2
"The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."