Von Hans Passant Kommentare und zusätzliche Tests auf meiner Seite, hier ist eine solidere Antwort:
Die 15.6ms (1/64 Sekunde) Grenze ist well-known unter Windows und ist das Standardverhalten. Es ist möglich, den Grenzwert (z. B. auf 1 ms durch einen Anruf auf timeBeginPeriod()
) zu senken, obwohl dies nicht empfohlen wird, da dies die globale System-Timer-Auflösung und die resultierende power consumption betrifft. Zum Beispiel Chrome is notorious for doing this. Aufgrund des globalen Aspekts der Zeitgeberauflösung kann daher aufgrund von Programmen von Drittanbietern eine Genauigkeit von 1 ms beobachtet werden, ohne explizit darum zu bitten.
sein Außerdem beachten Sie, dass std::chrono::high_resolution_clock
tut nicht auf Windows ein gültiges Verhalten haben (beide in Visual Studio oder MinGW Kontext). Sie können also nicht erwarten, dass diese Schnittstelle eine plattformübergreifende Lösung ist, und das 15.625ms-Limit gilt immer noch.
Wissen, wie können wir damit umgehen? Nun, man kann die timeBeginPeriod()
Sache verwenden, um die Genauigkeit einiger Timer zu erhöhen, aber wiederum sind wir nicht dazu raten: es scheint besser zu verwenden QueryPerformanceCounter()
(QPC), das ist die primäre API für nativen Code freut sich auf acquire high-resolution time stamps or measure time intervals laut Microsoft. Beachten Sie, dass GPC does count elapsed time (and not CPU cycles). Hier ist ein Anwendungsbeispiel:
LARGE_INTEGER StartingTime, EndingTime, ElapsedMicroseconds;
LARGE_INTEGER Frequency;
QueryPerformanceFrequency(&Frequency);
QueryPerformanceCounter(&StartingTime);
// Activity to be timed
QueryPerformanceCounter(&EndingTime);
ElapsedMicroseconds.QuadPart = EndingTime.QuadPart - StartingTime.QuadPart;
//
// We now have the elapsed number of ticks, along with the
// number of ticks-per-second. We use these values
// to convert to the number of elapsed microseconds.
// To guard against loss-of-precision, we convert
// to microseconds *before* dividing by ticks-per-second.
//
ElapsedMicroseconds.QuadPart *= 1000000;
ElapsedMicroseconds.QuadPart /= Frequency.QuadPart;
Nach Microsoft, QPC ist auch geeignet, in einem Multi-Core/Multi-Thread-Kontext, obwohl es weniger präzise sein kann/zweideutig:
Wenn Sie Leistungsindikatoren Ergebnisse vergleichen, die werden von verschiedenen Threads bezogen, berücksichtigen Sie Werte, die sich um ± 1 Tick unterscheiden, um eine mehrdeutige Ordnung zu haben. Wenn die Zeitstempel aus demselben Thread stammen, gilt diese Unsicherheit von ± 1 Tick nicht. In diesem Zusammenhang bezieht sich der Ausdruck Tick auf eine Zeitperiode gleich 1 ÷ (die Frequenz des Leistungszählers, erhalten von QueryPerformanceFrequency
).
Als zusätzliche Ressourcen, MS stellt auch eine FAQ on how/why use QPC und eine Erklärung auf clock/timing in Windows.
15.6 ist der normale Wert, es ist Ihre Win7-Installation, die sich schlecht benahm. Rufen Sie timeBeginPeriod() auf oder verwenden Sie QueryPerformanceCounter(), um eine Auflösung unter einer Mikrosekunde zu erhalten. QPF ist am besten. –
Wie kann ein "Fehlverhalten" besser sein? Kommt das von einer Konfigurationsoption? – cyrobin
Normal und "besser" haben gegnerische Ziele. Es ist rauh auf den Stromverbrauch, Sie werden eine Laptop-Batterie in Eile entleeren. Keine Konfiguration, normalerweise ein Programm oder Treiber, der timeBeginPeriod() aufruft. [Chrome ist dafür berüchtigt] (http: //blog.codinghorror.com/warum-hat-windows-haben-schrecklich-batterieleben /). Führen Sie powercfg -energy aus, um den Störenfried auf Win7 zu finden. –