Wie kann ich CPU Zykluszahl in Win32 erhalten?
-
02-07-2019 - |
Frage
In Win32 ist es eine Möglichkeit, eine einzigartige CPU Zykluszahl oder etwas ähnliches zu erhalten, die für mehrere Prozesse einheitlich sein würde / Sprachen / Systeme / etc.
Ich erstelle einige Log-Dateien, sondern müssen mehrere Log-Dateien erzeugen, weil wir die .NET-Laufzeit bewirten, und ich möchte Aufruf zu vermeiden, von einem zum anderen zu protokollieren. Als solches dachte ich werde ich zwei Dateien nur produzieren, kombiniere sie und wirft sie dann sortieren, eine kohärente Zeitleiste, die grenzüber Welt Anrufe zu erhalten.
Allerdings ist GetTickCount nicht für jeden Anruf zu erhöhen, so dass nicht zuverlässig ist. Gibt es eine bessere Zahl, so dass ich die Anrufe in der richtigen Reihenfolge erhalten, wenn Sortierung?
Bearbeiten : Dank @ Greg , die mich zu Queryperformancecounter auf der Strecke setzen , das war der Trick.
Lösung
Sie können über den RDTSC CPU-Anweisung (vorausgesetzt, x86). Diese Anweisung gibt die CPU-Zykluszähler, aber bewusst sein, dass es auf seinen Maximalwert sehr schnell zunehmen wird, und dann auf 0 zurückgesetzt Wie der Wikipedia-Artikel erwähnt, dass Sie die Queryperformancecounter Funktion.
Andere Tipps
Heres ein interessanter Artikel! sagt nicht RDTSC zu verwenden, sondern zu stattdessen Queryperformancecounter.
Fazit:
regelmäßige alte
timeGetTime()
Verwendung zu tun Timing ist nicht zuverlässig auf vielen Windows-basierte Betriebssysteme weil die Granularität des Systems Timer kann so hoch sein wie 10-15 Millisekunden, was bedeutet, dasstimeGetTime()
ist nur mit einer Genauigkeit 10-15 Millisekunden. [Notiere dass der hohe Granularität auftritt auf NT-basierten Betriebssysteme wie Windows NT, 2000 und XP. Windows 95 und 98 sind in der Regel viel besser Granularität zu haben, um 1-5 ms.]Wenn Sie jedoch anrufen
timeBeginPeriod(1)
am Anfang Ihr Programm (undtimeEndPeriod(1)
bei das Ende), wird in der RegeltimeGetTime()
werden genau 1-2 Millisekunden, und werden Sie mit extrem bieten genaue Timing-Informationen.
Sleep()
verhält sich ähnlich; die Länge die ZeitSleep()
tatsächlich schläft für geht Hand in Hand mit der Granularität vontimeGetTime()
, so dass nach AufruftimeBeginPeriod(1)
einmal,Sleep(1)
tatsächlich schlafen für 1-2 Millisekunden,Sleep(2)
für 2-3, und so auf (anstelle in Schritten von Schlaf so hoch wie 10 bis 15 ms).Für eine höhere Präzision Timing (Sub-Millisekunden-Genauigkeit), werden Sie wahrscheinlich wollen vermeiden, die Verwendung von Montage mnemonic RDTSC weil es schwer zu kalibrieren ; Verwenden Sie stattdessen
QueryPerformanceFrequency
undQueryPerformanceCounter
, welche präzise auf weniger als 10 Mikrosekunden (0,00001 Sekunden).Für einfaches Timing sowohl timeGetTime und Queryperformancecounter gut funktionieren, und ist Queryperformancecounter offensichtlich genauer. jedoch, wenn Sie müssen jede Art von „zeitlich tun Pausen“(wie jene, die für framerate Limiting), müssen Sie sein vorsichtig in einer Schleife Berufung des Sitzens Queryperformancecounter, warten auf es einen bestimmten Wert zu erreichen; dieser Wille auffressen 100% des Prozessors. Stattdessen betrachtet ein Hybrid-Schema, wo Sie Sleep (1) nennen (nicht vergessen timebeginperiod (1) zuerst!), wenn müssen Sie mehr als 1 ms passieren Zeit, und dann geben Sie nur die Queryperformancecounter 100% Besetzt- loop den letzten <1 / 1000stel eines beenden Sekunde der Verzögerung die Sie benötigen. Diese geben Ihnen ultra-präzise Verzögerungen (Accurate bis 10 Mikrosekunden), mit sehr geringe CPU-Auslastung. Sehen Sie den Code oben.
System.Diagnostics.Stopwatch.GetTimeStamp () gibt die Anzahl des CPU-Zyklus seit einem Zeitursprung (vielleicht, wenn der Computer gestartet werden, aber ich bin mir nicht sicher), und ich habe es nie nicht erhöht zwischen 2 Anrufen gesehen.
Die CPU-Zyklen werden für jeden Computer spezifisch sein, so dass Sie es nicht Protokolldatei zwischen zwei Computern verwenden können, fusionieren.
RDTSC Ausgang auf dem aktuellen Kern der Taktfrequenz abhängen kann, die für modernen CPUs ist weder konstant noch in einer Multi-Core-Maschine, konsistent.
Verwenden Sie die Systemzeit, und wenn mit Feeds Umgang von mehreren Systemen eine NTP-Zeitquelle verwenden. Sie können zuverlässige, konsistente Zeitmesswerte, die Quere kommen; wenn der Aufwand ist zu viel für Ihre Zwecke, die HPET Zeit, da die verstrichene zu arbeiten, letzte bekannte zuverlässige Zeitmesswert ist besser als die HPET allein.
die GetTickCount verwenden und einen anderen Zähler hinzufügen, wie Sie die Log-Dateien zusammenführen. Wollen Sie nicht perfekt Sequenz zwischen den verschiedenen Protokolldateien geben, aber es wird in der richtigen Reihenfolge aus jeder Datei alle Protokolle zumindest halten.