Okay, ich bind mir mal die Zeit für eine genaue Erklärung ans Bein.
Kurze Erklärung
@ kwinz: Glückwunsch. Du warst der Erste, der es geschnallt hat.
Lange Erklärung
Um in Windows Zeiten zu messen gibt es mehrere Möglichkeiten. Die Ur-Methode ist eine API-Funktion namens "GetTickCount()". Die liefert als Wert zurück, wieviele Millisekunden seit dem Start von Windows vergangen sind. Man hat also eine Auflösung von 1kHz. Für genaue Zeitmessungen war GetTickCount() also eher unbrauchbar, liefert aber immer konstante Ergebnisse. (Der Rückgabewert ist 32bittig, läuft also nach 49 Tagen über und beginnt wieder bei 0. Damit kamen bei Windows95 einige Systemdienste und Programme nicht klar, was zu den berühmten Abstürzen nach 49 Tagen Dauerbetrieb führte.)
Mit dem Pentium führte Intel den Zeitstempelzähler (Time Stamp Counter, ab jetzt TSC genannt) ein. Der TSC ist ein spezielles 64-Bit-Prozessorregister, welches die vergangenen Takte seit dem letzten Reset/Kaltstart mitzählt. Die Auflösung entspricht also der CPU-Taktfrequenz, was endlich genaue Messungen bis in den ns-Bereich möglich machte. Problem war nur, dass man als Programmierer nie wusste, wie schnell der TSC denn nun beim jeweiligen Anwender läuft. Das war aber früher nicht so schlimm. Da hat man den TSC mal eine Sekunde lang mit "GetTickCount()" verglichen und wusste danach die Taktfrequenz.
Der Ärger ging los, als die ersten Laptops mit Speedstep rauskamen. Da wurde der Prozessor je nach Last rauf- und runtergetaktet. Wenn jetzt ein Programm aber erstmal den TSC "eingemessen" hatte, waren die Zeitmessungen nach der dynamischen Taktänderung für die Tonne, das das Programm ja vom falschen Basistakt ausging. Dieser Fehler ist übrigens nicht Intel anzulasten. Der TSC war nur für Low-Level-Performancemessungen zur Codeoptimierung gedacht. Dass viele Programmierer das Ding auf einmal zur normalen Zeitmessung benutzen, hatte Intel nicht geplant.
Inzwischen hat Intel nachgegeben und bei den neuen Cores das Verhalten des TSC geändert. Wenn ein Prozessor in den Speed-Step-Modus geht, taktet er zwar runter, der TSC läuft aber mit der Normalfrequenz weiter. Damit ist der TSC zwar für die Codeoptimierung unbrauchbar (weil man keine echten Takte mehr zählen kann), die Zeitmessung wird aber nicht mehr verhunzt. Das gilt aber nur für Speedstep! Wenn man live am FSB dreht, ändert sich der TSC-Takt natürlich mit dem Prozessortakt.
Richtig lustig wird es, wenn mehrere Kerne im Prozessor sind. Jeder Kern hat seinen eigenen TSC und wenn die Kerne auch noch wegen irgendwelcher Stromspartechniken unterschiedlich takten, haben die TSCs auch unterschiedliche Werte. Wenn ein Programm jetzt den TSC abfragt, bekommt es den Wert von dem Kern, auf dem es gerade läuft. Da Windows laufende Programme aber beliebig zwischen den Kernen hin- und herschieben kann, "springen" die ausgelesenen TSC-Werte und laufen scheinbar sogar rückwärts. Das haben natürlich viele Programme nicht vertragen, weshalb es von AMD auch eine Software gibt, die die TSCs synchronisiert. (Ja, das ist der berühmte AMD-Dualcore-Fix.)
Bei Intel kann das übrigens auch passieren. Wenn man Extreme-Quadcores per Multiplikator übertaktet, läuft bei 2 Kernen der TSC u.U. noch mit der Originalfrequenz. Das ist ein Fehler im BIOS und lässt sich mit einem BIOS-Update beheben.
Okay, zurück zum Thema... "GetTickCount()" ist also zu langsam und beim TSC kann man sich nicht sicher sein, ob er konstant läuft. Also hat MS in Windows den High Performance Counter (HPC) eingebaut. Das Ding funzt eigentlich genauso wie "GetTickCount()" und wird mit "QueryPerformanceCounter" abgefragt. Allerdings steht hier die Frequenz nicht fest. Windows sucht sich beim Start die schnellste konstante Zeitquelle raus und verwendet sie als HPC-Grundtakt. Mit "QueryPerformanceFrequency" kann man die benutzte Frequenz abfragen.
Wenn Windows einen alten Pentium oder einen neuen Core mit oben erwähntem konstanten TSC findet, dann nimmt es den TSC (und damit den Prozessortakt) als Zeitgrundlage für den HPC. Wenn der Verdacht besteht, dass der TSC variiert, dann wird meisstens eine Zeitbasis von ca. 3,5 MHz (der ACPI-Timer) benutzt. Auch hier rechnet niemand damit, dass jemand im laufenden Betrieb am FSB dreht und damit den TSC-Takt verändert. Es geht nur um Cool'n'Quiet, SpeedStep, etc...
So, genug der grauen Theorie, hier etwas Praxis:
Ich hab mal eine Timerklasse (Teil eines größeren Programmes, welches eine genaue Zeitmessung benötigt) geschreiben. Um die oben erwähnten Effekte in der Realität auszutesten (einiges war mir damals noch unbekannt) hab ich schnell ein q'n'dirty-Testprogramm zusammengepanscht. Wundert Euch daher nicht über die komische Oberfläche und Startposition.
Taktfrequenz Prozessor -> eigentlich falsch, hier wird der aktuelle Takt vom TSC angezeigt (Den echten CPU-Takt gibts z.B. mit CPUz.) Mit den CPU-Häkchen kann man festlegen, auf welchen Kernen das Programm laufen soll. (Um evtl. Unterschiede in den TSC-Frequenzen zu finden)
Taktfrequenz HPC -> der von Windows angegebene Takt für den HPC
Wenn hier fast der gleiche Wert steht, wie bei "Taktfrequenz Prozessor", dann dient der TSC als HPC-Grundlage.
Mit "HPC benutzt" kann man die Verwendung des HPC im Testprogramm ausschalten. Dann wird immer "GetTickCount()" verwendet.
Mit "Prozessorlast" kann man die CPU etwas rödeln lassen, um die Wirkung von SpeedStep und Co. zu sehen.
Alle, die den "mehr FPS bei weniger Takt"-Effekt haben, tun bitte folgendes:
- Windows mit "hochgetaktetem" Prozessor hochfahren
- Timercheck starten, HPC einschalten und Testtimer laufenlassen
- jetzt mit euren Tools den FSB runtertakten
Wenn HPC und TSC-Takt die gleichen Werte hatten, werdet ihr vermutlich folgende Beobachtung machen:
- der TSC-Takt wird kleiner
- der HPC-Takt bleibt gleich (weil der Wert nur einmal von Windows ermittelt wird)
- die Timerklasse wird gegenüber dem Windows-Timer langsamer (Ich gehe mal davon aus, dass der Windows-Timer konstant bleibt. Da ich nicht weiss, wo eure Übertaktungssoftware dran rumdreht, könnte ich mich aber auch irren. Dann würde sogar der Windows-Timer langsamer laufen und ihr müsstet mit der Stoppuhr nachprüfen.)
Wenn dies der Fall ist, dann laufen jetzt alle Programme, die den HPC benutzen langsamer, bzw. messen kleinere Zeiten.
Wenn ein Programm den TSC benutzt hängt es davon ab, wann es seinen "Basistakt" gemessen hat. Wenn ihr den FSB vorher einstellt, ist alles OK. Wenn ihr danach dran rumdreht, kommt wieder Müll raus...
Beim "dynamischen Übertakten" kommt also schnell Murks bei Zeitmessungen raus. Man kann aber Korrekturrechnen:
Snipermike hat von 3,6 GHz auf 3,2 GHz runtergedreht. Es wurde also mit 3,2 GHz Takt gemessen, aber mit 3,6 GHz gerechnet. Gemessene Zeiten müssen also mit 3,6 GHZ multipliziert werden um die tatsächlichen Taktzyklen zu ermitteln. Dann muss man durch den echten Takt, also 3,2 GHz, teilen.
Da FPS=1/Zeit gilt:
echte FPS= (gemessene FPS * 3,2)/3,6
Dann sollte eigentlich der echte Wert rauskommen. Da durch den veränderten Timer aber das ganze Spiel anders läuft, kann es auch wirkliche Abweichungen bei den FPS geben.
Puh, das war jetzt viel "high tech shit", aber die Moral von der Geschicht ist:
Nicht bei laufendem Windows am Takt rumschrauben. Das gibt nur Probleme...