GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Zeit in Linux messen - Zeit vs. Uhr vs. getrusage vs. clock_gettime vs. gettimeofday vs. timespec_get?

Das Problem besteht darin, dass in C und C++ mehrere verschiedene Zeitfunktionen verfügbar sind, von denen sich einige im Verhalten zwischen den Implementierungen unterscheiden. Es gibt auch viele Halbantworten, die herumschwirren. Das Zusammenstellen einer Liste von Uhrfunktionen zusammen mit ihren Eigenschaften würde die Frage richtig beantworten. Lassen Sie uns zunächst fragen, was die relevanten Eigenschaften sind, nach denen wir suchen. Wenn ich mir Ihren Beitrag ansehe, schlage ich vor:

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

Bevor ich mit der Liste beginne, möchte ich darauf hinweisen, dass die Wanduhrzeit selten die richtige Zeit ist, während sie sich mit Zeitzonenänderungen, Sommerzeitumstellungen oder wenn die Wanduhr über 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 Schreibtisch).

Folgendes habe ich bisher für Uhren in Linux und OS X gefunden:

  • time() gibt die Wanduhrzeit vom Betriebssystem 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 auf meinem System beträgt tatsächlich 1 µs. Dieser Takt läuft um, sobald er seinen Höchststand erreicht hat (dies geschieht normalerweise nach ~2^32 Ticks, was für einen 1-MHz-Takt nicht sehr lang ist). man clock sagt, dass es seit glibc 2.18 mit clock_gettime(CLOCK_PROCESS_CPUTIME_ID, ...) implementiert ist unter Linux.
  • clock_gettime(CLOCK_MONOTONIC, ...) liefert Nanosekundenauflösung, ist monoton. Ich glaube, die "Sekunden" und "Nanosekunden" werden separat gespeichert, jeweils in 32-Bit-Zählern. Somit würde ein Umbruch nach vielen Dutzend Jahren Betriebszeit erfolgen. Das sieht nach einer sehr guten Uhr aus, ist aber leider noch nicht für OS X verfügbar. POSIX 7 beschreibt CLOCK_MONOTONIC als optionale Erweiterung.
  • getrusage() stellte sich für meine Situation als die beste Wahl heraus. Es meldet die Benutzer- und Systemzeiten separat und läuft nicht herum. Die Genauigkeit auf meinem System 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 war die Genauigkeit nur 1 ms.
  • gettimeofday() gibt die Uhrzeit mit (nominell) µs Genauigkeit zurück. Auf meinem System scheint diese Uhr eine µs-Genauigkeit zu haben, aber dies ist nicht garantiert, weil "die Auflösung der Systemuhr hardwareabhängig ist". POSIX.1-2008 sagt das. "Anwendungen sollten den clock_gettime() verwenden Funktion anstelle des veralteten gettimeofday() function", also sollten Sie die Finger davon lassen. 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 ns-Auflösung. Im Prinzip läuft diese Uhr herum, aber sie speichert ns mit einer 64-Bit-Ganzzahl ohne Vorzeichen, sodass das Umbrechen in der Praxis kein Problem sein sollte. Portabilität ist fraglich.
  • Ich habe eine Hybridfunktion basierend auf diesem Ausschnitt geschrieben, die clock_gettime verwendet, wenn sie unter Linux kompiliert wird, oder einen Mach-Timer, wenn sie unter OS X kompiliert wird, um sowohl unter Linux als auch unter OS X ns-Präzision zu erhalten.

Alle oben genannten sind sowohl in Linux als auch in OS X vorhanden, sofern nicht anders angegeben. „Mein System“ oben 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:

  • http://blog.habets.pp.se/2010/09/gettimeofday-should-never-be-used-to-measure-time
  • Wie misst man die TATSÄCHLICHE Ausführungszeit eines C-Programms unter Linux?
  • http://digitalsandwich.com/archives/27-benchmarking-misconceptions-microtime-vs-getrusage.html
  • http://www.unix.com/hp-ux/38937-getrusage.html

Aktualisieren :für OS X, clock_gettime wurde ab 10.12 (Sierra) implementiert. Außerdem teilen sich sowohl POSIX- als auch BSD-basierte Plattformen (wie OS X) den rusage.ru_utime Strukturfeld.


C11 timespec_get

Anwendungsbeispiel unter:https://stackoverflow.com/a/36095407/895245

Die maximal mögliche zurückgegebene Genauigkeit beträgt Nanosekunden, aber die tatsächliche Genauigkeit ist implementierungsdefiniert und könnte 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 direkt weiter an:

clock_gettime (CLOCK_REALTIME, ts) < 0)

clock_gettime und CLOCK_REALTIME sind POSIX http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_getres.html und man clock_gettime sagt, dass diese Maßnahme Diskontinuitäten haben kann, wenn Sie eine Systemzeiteinstellung ändern, während Ihr Programm läuft.

C++11-Chrono

Da wir gerade dabei sind, wollen wir sie auch behandeln:http://en.cppreference.com/w/cpp/chrono

GCC 5.3.0 (C++ stdlib ist innerhalb der GCC-Quelle):

  • high_resolution_clock ist ein Alias ​​für system_clock
  • system_clock leitet zum ersten der folgenden verfügbaren Elemente weiter:
    • clock_gettime(CLOCK_REALTIME, ...)
    • gettimeofday
    • time
  • steady_clock leitet zum ersten der folgenden verfügbaren Elemente weiter:
    • clock_gettime(CLOCK_MONOTONIC, ...)
    • system_clock

Gefragt bei:Unterschied zwischen std::system_clock und std::steady_clock?

CLOCK_REALTIME gegenüber CLOCK_MONOTONIC :Unterschied zwischen CLOCK_REALTIME und CLOCK_MONOTONIC?


Linux
  1. Linux – Wie misst und verhindert man Uhrdrift?

  2. Beispiele für Linux-Zeitbefehle

  3. timedatectl-Befehlsbeispiele in Linux

  4. Linux-Prozesszustände

  5. Kompilieren von C++ auf einem Remote-Linux-Rechner – Warnung vor Uhrversatz erkannt

Linux-Zeitbefehl

Letzter Befehl in Linux

Überprüfen Sie die Zeitzone in Linux

Beispiele für Linux-Datumsbefehle

Verstehen des Zeitbefehls in Linux

Linux-Ping:Zeitüberschreitung anzeigen