AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi Taktfrequenz berechnen, Realtime Counter, Überlauf ?
Thema durchsuchen
Ansicht
Themen-Optionen

Taktfrequenz berechnen, Realtime Counter, Überlauf ?

Ein Thema von El.Blindo · begonnen am 27. Jan 2008 · letzter Beitrag vom 28. Jan 2008
 
El.Blindo

Registriert seit: 24. Okt 2006
18 Beiträge
 
#1

Taktfrequenz berechnen, Realtime Counter, Überlauf ?

  Alt 27. Jan 2008, 14:25
Moin erstmal,

Ich bin ja schon eine Weile hier angemeldet, und habe mir auch schon die eine oder andere "Anregung" hier geholt.
Die meisten meiner kleinen Probleme haben sich bisher durch aufmerksames Lesen von Foren-Beiträgen gelöst.

Nun stehe ich allerdings vor einem Problem, bei dem ich nicht weiter komme.

Zur Erläuterung:

Sinn der Sache ist es auf Core 2 Prozessoren die aktuelle Taktfrequenz zu berechnen, ohne eine nennenswerte CPU-Last zu erzeugen. Verwendet wird hier Winring0 eine OpenSys Library.
Wie vielleicht bekannt ist konnte auf "älteren" Prozessoren die Taktfrequenz alleine über den Realtime Counter, sowie über den Performance Counter bestimmt werden.
Neuere Prozessoren, so auch der Core 2, haben einen konstanten TSC (Constant_TSC), d.h. unabhängig von der aktuellen Taktfrequenz wird der Realtime Counter mit der nominellen Taktfrequenz betrieben.

Ich habe mich in den letzten Tagen eingehend mit Intel Datenblättern und verschiedenen Counterwerten beschäftigt und bin zu dem Code der hier einfügt ist gekommen.

Verwendet werden hier zusätzlich IA32_APERF_MSR und IA32_MPERF_MSR.

IA32_APERF_MSR gibt die Anzahl der Taktzyklen wieder die sich der Prozessor im C0 State befand, bezogen auf die aktuelle Taktfrequenz.

IA32_MPERF_MSR gibt die Anzahl der Taktzyklen wieder die sich der Prozessor im C0 State befand, bezogen auf die nominelle Taktfrequenz.

Nun zum Problem: T_Delta wird in meinem Code als DWord deklariert, richtig wäre eigentlich Int64. Wenn ich T_Delta jedoch als Int64 deklariere treten bei der Berechnung der Taktfrequenz negative Werte auf.
Scheinbar gibt es Probleme damit das Int64 ein signed Wert ist, die Ausgabe des Realtime Counters jedoch ein unsigned Wert.

Hat jemand eine Idee wie dieses Problem zu lösen ist ?

Ich hänge sicherheitshalber noch einmal das gesamte Projekt an.


Delphi-Quellcode:
procedure TForm1.Timer1Timer(Sender: TObject);
var
  EAX, EDX : DWord; //Variablen für Register Übergabe
  Frequency : Int64; //Performance Counter Frequency
  P_Count : Int64; //Performance Counter aktueller Wert
  A_Count : Int64; //IA32_APERF_MSR Aktueller Wert
  M_Count : Int64; //IA32_MPERF_MSR Aktueller Wert
  T_Count : Int64; //Realtime Counter Aktueller Wert
  P_Delta : Int64; //Performance Counter Delta Wert
  A_Delta : Int64; //IA32_APERF_MSR Delta Wert
  M_Delta : Int64; //IA32_MPERF_MSR Delta Wert
  T_Delta : DWord; //Sollte eigentlich auch Int64 sein !!!
  PC,PT : Cardinal;
  Nominal : Integer;
  Aktuell : Integer;
begin
  // Routine läuft nur auf Core1
  SetThreadAffinityMaskByID(GetCurrentThreadID, 1);
  // Sichern der alten Prioritäten
  PC := GetPriorityClass(GetCurrentProcess);
  PT := GetThreadPriority(GetCurrentThread);
  // Höchste Priorität
  SetPriorityClass(GetCurrentProcess, REALTIME_PRIORITY_CLASS);
  SetThreadPriority(GetCurrentThread, THREAD_PRIORITY_TIME_CRITICAL);
  // Performance Counter und Frequenz abfragen und merken
  QueryPerformanceFrequency(Frequency);
  QueryPerformanceCounter(P_Count);
  // Realtime Counter abfragen und merken
  Rdtsc(EAX,EDX);
  T_Count := EAX + EDX shl 16;
  // IA32_APERF_MSR abfragen und merken
  Rdmsr(IA32_APERF_MSR,EAX,EDX);
  A_Count := EAX + EDX shl 16;
  // IA32_MPERF_MSR abfragen und merken
  Rdmsr(IA32_MPERF_MSR,EAX,EDX);
  M_Count := EAX + EDX shl 16;
  //Warten ohne CPU-Last, die genauigkeit steigt mit steigender Wartezeit
  Sleep(250);
  // Performance Counter und Delta berechnen
  QueryPerformanceCounter(P_Delta);
  P_Delta := P_Delta-P_Count;
  // Realtime Counter abfragen und Delta berechnen
  Rdtsc(EAX,EDX);
  T_Delta := (EAX + EDX shl 16) - T_Count;
  // IA32_APERF_MSR abfragen und Delta berechnen
  Rdmsr(IA32_APERF_MSR,EAX,EDX);
  A_Delta := (EAX + EDX shl 16) - A_Count;
  // IA32_MPERF_MSR abfragen und Delta berechnen
  Rdmsr(IA32_MPERF_MSR,EAX,EDX);
  M_Delta := (EAX + EDX shl 16) - M_Count;
  // Berechnung der nominellen Taktfrequenz (Constant_TSC)
  Nominal := Round(T_Delta/(P_Delta/Frequency)/1000000);
  // Berechnung der aktuellen Taktfrequenz
  Aktuell := Round(Nominal*(A_Delta/M_Delta)+0.5);
  // Alte Prioritäten wiederherstellen
  SetThreadPriority(GetCurrentThread, PT);
  SetPriorityClass(GetCurrentProcess, PC);
  Memo1.Lines.Add('Nomineller Prozessortakt : '+ IntToStr(Nominal));
  Memo1.Lines.Add('Aktueller Prozessortakt : '+ IntToStr(Aktuell));
  Memo1.Lines.Add('');
end;
MfG

El.Blindo
Angehängte Dateien
Dateityp: zip perfmsr_541.zip (43,8 KB, 16x aufgerufen)
  Mit Zitat antworten Zitat
 


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:57 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz