Ich habe kürzlich entschieden, dass ich für meine Timer-Klasse von Millisekunden auf Mikrosekunden umsteigen muss, und nach einigen Recherchen habe ich entschieden, dass QueryPerformanceCounter wahrscheinlich meine sicherste Wahl ist. (Die Warnung, Boost::Posix
dass es unter Win32-API möglicherweise nicht funktioniert, hat mich etwas abgeschreckt). Ich bin mir jedoch nicht sicher, wie ich es implementieren soll.
Ich rufe die von GetTicks()
mir verwendete Esque-Funktion auf und weise sie der Timer- startingTicks
Variablen zu. Um die verstrichene Zeit zu ermitteln, subtrahiere ich einfach den Rückgabewert der Funktion von startingTicks
und wenn ich den Timer zurücksetze, rufe ich die Funktion erneut auf und weise ihr Start-Ticks zu. Leider ist der Code, den ich gesehen habe, nicht so einfach wie das bloße Aufrufen QueryPerformanceCounter()
, und ich bin mir nicht sicher, was ich als Argument übergeben soll.
Antworten:
Dieses Programm sollte eine Zahl nahe 1000 ausgeben (Windows Sleep ist nicht so genau, sollte aber 999 sein).
Die
StartCounter()
Funktion zeichnet die Anzahl der Ticks auf, die der Leistungsindikator in derCounterStart
Variablen hat. DieGetCounter()
Funktion gibt die Anzahl der Millisekunden seit demStartCounter()
letzten Aufruf als Double zurück. Wenn alsoGetCounter()
0,001 zurückgegeben wird, ist seit demStartCounter()
Aufruf etwa 1 Mikrosekunde vergangen .Wenn Sie möchten, dass der Timer stattdessen Sekunden verwendet, ändern Sie ihn
zu
oder wenn Sie Mikrosekunden wollen, dann verwenden Sie
Aber es geht wirklich um Bequemlichkeit, da es ein Doppel zurückgibt.
quelle
On a multiprocessor computer, it should not matter which processor is called. However, you can get different results on different processors due to bugs in the basic input/output system (BIOS) or the hardware abstraction layer (HAL).
Dieser Code ist nicht stark fehlerhaft, sondern ein BIOS oder HAL.StartCounter
Funktion den folgenden Aufruf hinzugefügt :old_mask = SetThreadAffinityMask(GetCurrentThread,1);
und ihn am Ende zurückgesetztSetThreadAffinityMask ( GetCurrentThread , old_mask ) ;
. Ich hoffe, das wird den Trick machen. Dies sollte verhindern, dass mein Thread auf etwas anderes als den 1. CPU-Kern verschoben wird. (Was offensichtlich nur eine Lösung für eine Testumgebung ist)Ich benutze diese Definitionen:
Verwendung (Klammern zur Vermeidung von Neudefinitionen):
Ausgabe aus Verwendungsbeispiel:
quelle
Angenommen, Sie arbeiten unter Windows (wenn ja, sollten Sie Ihre Frage als solche kennzeichnen !), Finden Sie auf dieser MSDN-Seite die Quelle für eine einfache, nützliche
HRTimer
C ++ - Klasse, die die erforderlichen Systemaufrufe umschließt, um etwas zu tun, das Ihren Anforderungen sehr nahe kommt (Es wäre einfach, eineGetTicks()
Methode hinzuzufügen , insbesondere um genau das zu tun , was Sie benötigen).Auf Nicht-Windows-Plattformen gibt es keine QueryPerformanceCounter-Funktion, sodass die Lösung nicht direkt portierbar ist. Wenn Sie es jedoch in eine Klasse wie die oben genannte einbinden
HRTimer
, ist es einfacher, die Implementierung der Klasse zu ändern, um das zu verwenden, was die aktuelle Plattform tatsächlich bieten kann (möglicherweise über Boost oder was auch immer!).quelle
Ich würde diese Frage mit einem NDIS-Treiberbeispiel zum Erhalten von Zeit erweitern. Wie bekannt ist, hat KeQuerySystemTime (nachgeahmt unter NdisGetCurrentSystemTime) eine niedrige Auflösung über Millisekunden, und es gibt einige Prozesse wie Netzwerkpakete oder andere IRPs, die möglicherweise einen besseren Zeitstempel benötigen.
Das Beispiel ist genauso einfach:
wobei der Divisor 10 ^ 3 oder 10 ^ 6 ist, abhängig von der erforderlichen Auflösung.
quelle