Unter den Zeitfunktionen time
, clock
getrusage
, clock_gettime
, gettimeofday
und timespec_get
, Ich möchte klar verstehen, wie sie implementiert sind und was ihre Rückgabewerte sind, um zu wissen, in welcher Situation ich sie verwenden muss.
Zuerst müssen wir Funktionen klassifizieren, die Wanduhr-Werte zurückgeben, und mit Funktionen vergleichen, die Prozess- oder Thread-Werte zurückgeben. gettimeofday
gibt den Wert der Wanduhr zurück, clock_gettime
gibt den Wert der Wanduhr zurück oder Prozess- oder Thread-Werte, abhängig vom übergebenen Parameter Clock
. getrusage
und clock
geben Prozesswerte zurück.
Die zweite Frage betrifft dann die Implementierung dieser Funktionen und infolgedessen deren Genauigkeit. Welchen Hardware- oder Softwaremechanismus verwenden diese Funktionen?.
Es scheint, dass getrusage
nur den Kernel-Tick (normalerweise 1 ms lang) verwendet und daher nicht genauer als die ms sein kann. Ist es richtig? Dann scheint die Funktion getimeofday
die genaueste zugrunde liegende verfügbare Hardware zu verwenden. Infolgedessen ist seine Genauigkeit in der Regel die Mikrosekunde (kann aufgrund der API nicht länger sein) auf neuerer Hardware. Was ist mit clock
, die Manpage spricht von "Approximation", was bedeutet das? Wie wäre es mit clock_gettime
Die API befindet sich in Nanosekunden. Bedeutet dies, dass sie so genau sein kann, wenn die zugrunde liegende Hardware dies zulässt? Was ist mit Monotonie?
Gibt es noch andere Funktionen?
Das Problem ist, dass in C und C++ verschiedene Zeitfunktionen verfügbar sind und einige von ihnen sich in ihrem Verhalten zwischen den Implementierungen unterscheiden. Es gibt auch viele Halbantworten. Das Zusammenstellen einer Liste von Uhrfunktionen mit ihren Eigenschaften würde die Frage richtig beantworten. Fragen wir zunächst, nach welchen relevanten Eigenschaften wir suchen. Wenn ich mir deinen Beitrag ansehe, schlage ich vor:
Bevor ich mit der Liste beginne, möchte ich darauf hinweisen, dass die Wanduhr selten die richtige Zeit ist, während sie sich mit Zeitzonenänderungen, Änderungen der Sommerzeit oder wenn die Wanduhr von NTP synchronisiert wird, ändert. Keines dieser Dinge ist gut, wenn Sie die Zeit nutzen, um Ereignisse zu planen oder die Leistung zu bewerten. Es ist nur wirklich gut für das, was der Name sagt, eine Uhr an der Wand (oder auf dem Desktop).
Folgendes habe ich bisher für Uhren unter Linux und OS X gefunden:
time()
gibt die Uhrzeit des Betriebssystems mit einer Genauigkeit in Sekunden zurück.clock()
scheint die Summe aus Benutzer- und Systemzeit zurückzugeben. Es ist in C89 und höher vorhanden. Früher sollte dies die CPU-Zeit in Zyklen sein, aber moderne Standards wie POSIX verlangen, dass CLOCKS_PER_SEC 1000000 ist, was eine maximal mögliche Genauigkeit von 1 µs ergibt. Die Genauigkeit meines Systems beträgt in der Tat 1 µs. Diese Uhr läuft nach dem Auffüllen um (dies geschieht normalerweise nach ~ 2 ^ 32 Ticks, was für eine 1-MHz-Uhr nicht sehr lang ist). man clock
Sagt, dass es seit glibc 2.18 mit clock_gettime(CLOCK_PROCESS_CPUTIME_ID, ...)
in Linux implementiert ist.clock_gettime(CLOCK_MONOTONIC, ...)
liefert eine Nanosekundenauflösung und ist monoton. Ich glaube, die Sekunden und Nanosekunden werden getrennt in 32-Bit-Zählern gespeichert. Somit würde jede Umgehung nach vielen Dutzend Jahren Betriebszeit auftreten. Dies sieht nach einer sehr guten Uhr aus, ist aber unter OS X leider noch nicht verfügbar. POSIX 7 beschreibt CLOCK_MONOTONIC
Als optionale Erweiterung .getrusage()
erwies sich als die beste Wahl für meine Situation. Es meldet die Benutzer- und Systemzeiten getrennt und führt keinen Umlauf durch. Die Genauigkeit meines Systems beträgt 1 µs, aber ich habe es auch auf einem Linux-System (Red Hat 4.1.2-48 mit GCC 4.1.2) getestet und dort betrug die Genauigkeit nur 1 ms.gettimeofday()
gibt die Wanduhrzeit mit (nominal) µs Genauigkeit zurück. Auf meinem System scheint diese Uhr µs-genau zu sein, dies kann jedoch nicht garantiert werden, da "die Auflösung der Systemuhr ist hardwareabhängig" . POSIX.1-2008 sagt das . "Anwendungen sollten die clock_gettime()
-Funktion anstelle der veralteten gettimeofday()
-Funktion verwenden", also sollten Sie sich davon fernhalten. Linux x86 und implementiert es als Systemaufruf .mach_absolute_time()
ist eine Option für das Timing mit sehr hoher Auflösung (ns) unter OS X. Auf meinem System ergibt dies tatsächlich eine Auflösung von ns. Im Prinzip läuft diese Uhr rund, speichert jedoch ns mit einer 64-Bit-Ganzzahl ohne Vorzeichen, sodass das Umlaufen in der Praxis kein Problem sein sollte. Portabilität ist fraglich.Alle oben genannten Funktionen stehen sowohl unter Linux als auch unter OS X zur Verfügung, sofern nicht anders angegeben. "Mein System" im obigen Beispiel ist ein Apple mit OS X 10.8.3 mit GCC 4.7.2 von MacPorts.
Schließlich ist hier eine Liste von Referenzen, die ich zusätzlich zu den obigen Links hilfreich fand:
Update : Für OS X wurde ab 10.12 (Sierra) clock_gettime
Implementiert. Sowohl POSIX- als auch BSD-basierte Plattformen (wie OS X) haben das Strukturfeld rusage.ru_utime
Gemeinsam.
C11 timespec_get
Verwendungsbeispiel unter: https://stackoverflow.com/a/36095407/895245
Die maximal mögliche Genauigkeit, die zurückgegeben wird, ist Nanosekunden, die tatsächliche Genauigkeit ist jedoch in der Implementierung definiert und kann kleiner sein.
Es gibt die Wandzeit zurück, nicht die CPU-Auslastung.
glibc 2.21 implementiert es unter sysdeps/posix/timespec_get.c
und leitet es direkt weiter an:
clock_gettime (CLOCK_REALTIME, ts) < 0)
clock_gettime
Und CLOCK_REALTIME
Lauten POSIX http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_getres.html und man clock_gettime
Wenn Sie während der Ausführung Ihres Programms eine Systemzeiteinstellung ändern, kann dies zu Diskontinuitäten führen.
C++ 11 Chrono
Da wir schon dabei sind, wollen wir sie auch behandeln: http://en.cppreference.com/w/cpp/chrono
GCC 5.3.0 (C++ stdlib ist in der GCC-Quelle enthalten):
high_resolution_clock
ist ein Alias für system_clock
system_clock
leitet an die erste der folgenden Möglichkeiten weiter: clock_gettime(CLOCK_REALTIME, ...)
gettimeofday
time
steady_clock
leitet an die erste der folgenden Möglichkeiten weiter: clock_gettime(CLOCK_MONOTONIC, ...)
system_clock
Gefragt bei: nterschied zwischen std :: system_clock und std :: steady_clock?
CLOCK_REALTIME
Vs CLOCK_MONOTONIC
: nterschied zwischen CLOCK_REALTIME und CLOCK_MONOTONIC?