webentwicklung-frage-antwort-db.com.de

Zeit in Linux messen - Zeit gegen Uhr gegen Getrusage gegen Clock_gettime gegen Gettimeofday gegen Timespec_get?

Unter den Zeitfunktionen time, clockgetrusage, 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?

137
Manuel Selva

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:

  • Welche Zeit wird von der Uhr gemessen? (echt, Benutzer, System oder hoffentlich nicht Wanduhr?)
  • Wie genau ist die Uhr? (s, ms, µs oder schneller?)
  • Nach wie viel Zeit dreht sich die Uhr? Oder gibt es einen Mechanismus, um dies zu vermeiden?
  • Ist die Uhr monoton oder ändert sie sich mit Änderungen der Systemzeit (über NTP, Zeitzone, Sommerzeit, vom Benutzer usw.)?
  • Wie unterscheiden sich die obigen Angaben zwischen den Implementierungen?
  • Ist die spezifische Funktion veraltet, nicht standardisiert usw.?

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.
  • Ich habe eine hybride Funktion geschrieben basierend auf diesem Snippet , die clock_gettime verwendet, wenn sie unter Linux kompiliert wird, oder einen Mach-Timer, wenn sie unter OS X kompiliert wird, um unter beiden Linux ns-Präzision zu erreichen und OS X.

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.

183

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?