Sonntag, 11. August 2013

Extremgenaue Zeitmessung mit Assemblerbefehl RDTSC bei neueren Intelprozessoren wieder möglich

Ich hatte den Assemblerbefehl RDTSC in früheren Zeiten mit einem Prozessor, sprich "Single Core", sehr gerne für genaue Zeitmessungen/Profiling von Delphi-Programmroutinen verwendet. Doch mit der Verwendung von Dual Core oder Mehrkernprozessoren und Stromsparfunktionen arbeitete RDTSC nicht mehr mit einer konstanten Rate, sodass damit verläßliche Zeitmessungen nicht mehr möglich wurden und verwendete stattdessen die Windows API Queryperformancecounter. Doch vor einiger Zeit habe ich bemerkt, dass der RDTSC bei neueren Prozessoren wieder mit einer konstanten Rate arbeitet. Es scheint so zu sein, dass ab der Intel Nehalem Generation der RDTSC ähnlich wie bei AMD mit konstanter Rate unabhängig von der aktuellen Taktfrequenz läuft. Dieses Feature wird bei Intel mit "invariant TSC" bezeichnet.

Ob ein Prozessor invariant TSC unterstützt kann man mit CPUID 80000007H:EDX[8] abfragen. Dies kann man in der aktuellen "Intel® 64 and IA-32 Architectures Software Developer Manuals" unter Kapitel "17.13.1 Invariant TSC" (Stand June 2013) nachlesen.
Da die aktuelle Jedi Bibliothek sehr viel von CPUID ausliest, habe ich diese verwendet um dieses Bit auszulesen. Die JclSysInfo.pas stellt die Funktionen bereit, die für das auslesen von CPUID benötigt werden. Darum habe ich sinngemäß die JclSysInfo.pas um folgende paar Zeilen ergänzt.

var
  RDTSCInfo : Cardinal;
begin
  CallCPUID($80000007, 0, Unused, Unused, Unused, RDTSCInfo);  
end;


Das coole bei invariant TSC ist, dass das RDTSC Hagen Beispiel auch auf einem Intel i7 ohne Probleme läuft.

Quellen und weiterführende Literatur:

Keine Kommentare: