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

Lesezeit: 7 Minuten

Benutzeravatar von Manuel Selva
Manuel Selva

Unter den Timing-Funktionen time, clock getrusage, clock_gettime, gettimeofday und timespec_getmöchte ich 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 zurückkehrende Funktionen klassifizieren Wanduhrwerte Vergleichen Sie mit Funktionen, die zurückkehren Prozess- oder Thread-Werte. gettimeofday gibt den Wert der Wanduhr zurück, clock_gettime gibt den Wert der Wanduhr zurück oder Prozess- oder Thread-Werte abhängig von der Clock Parameter übergeben. getrusage und clock Prozesswerte zurückgeben.

Dann betrifft die zweite Frage die Implementierung dieser Funktionen und folglich ihre Genauigkeit. Welche Hardware- oder Softwaremechanismen verwenden diese Funktionen?

Es scheint, dass getrusage verwendet nur den Kernel-Tick (normalerweise 1 ms lang) und kann daher nicht genauer als ms sein. Ist es richtig? Dann ist die getimeofday Die Funktion scheint die genaueste verfügbare zugrunde liegende Hardware zu verwenden. Infolgedessen beträgt die Genauigkeit auf neuerer Hardware normalerweise die Mikrosekunde (kann aufgrund der API nicht mehr sein). Wie wäre es mit clock, die Manpage spricht von “Approximation”, was bedeutet das? Wie wäre es mit clock_gettime, die API ist in Nanosekunden, bedeutet das, dass sie so genau sein kann, wenn die zugrunde liegende Hardware dies zulässt? Was ist mit Monotonie?

Gibt es noch andere Funktionen?

Benutzeravatar von Douglas B. Staple
Douglas B. Grundnahrungsmittel

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 deinen Beitrag ansehe, schlage ich vor:

  • Welche Zeit misst die Uhr? (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 Uhrzeit der Wanduhr 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 erfordern, 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 implementiert ist clock_gettime(CLOCK_PROCESS_CPUTIME_ID, ...) 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 das ist nicht garantiert, weil “Die Auflösung der Systemuhr ist hardwareabhängig”. POSIX.1-2008 sagt, dass. „Anwendungen sollten die verwenden clock_gettime() Funktion statt Obsoleszenz gettimeofday() function”, 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 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. Die Portabilität ist fraglich.
  • Ich habe eine Hybridfunktion basierend auf geschrieben dieser Ausschnitt das verwendet clock_gettime, wenn es unter Linux kompiliert wird, oder einen Mach-Timer, wenn es unter OS X kompiliert wird, um sowohl unter Linux als auch unter OS X eine 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.

Abschließend ist hier eine Liste von Referenzen, die ich zusätzlich zu den obigen Links hilfreich fand:


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) die rusage.ru_utime struct-Feld.

  • Mac OS X hat das nicht clock_gettimedaher die Verwendung von gettimeofday() ein wenig vielseitiger als clock_gettime()

    – bobobobo

    17. April 2013 um 4:30 Uhr


  • Du hast es nicht erwähnt times() (mit einem s), das in POSIX seit Ausgabe 1 existiert. Bezüglich GNU/Linux: Laut der Manpage clock(3) clock() von glibc 2.17 und früher wurde darüber implementiert, aber für eine verbesserte Genauigkeit ist es jetzt darüber implementiert clock_gettime(CLOCK_PROCESS_CPUTIME_ID,...)die auch in POSIX angegeben wird, aber optional ist.

    – vinc17

    11. September 2014 um 15:02 Uhr

  • @starflyer Die Genauigkeit der Uhr wird teilweise durch die Zeit begrenzt, die zum Abfragen der Uhr benötigt wird. Dies liegt daran, dass, wenn ich die Uhr anrufe und die Rückkehr 1 µs dauert, die Uhrzeit, die die Uhr meldet, aus Sicht des Anrufers um 1 µs “aus” ist. Das bedeutet, dass eine hochgenaue Uhr auch eine niedrige Latenzzeit haben muss. Normalerweise muss man also nicht den Kompromiss eingehen, von dem Sie sprechen: Die billigsten Uhren sind auch die genauesten.

    – Douglas B. Staple

    23. März 2015 um 23:53 Uhr

  • Auch kümmern sich die meisten Uhren nicht um Sommerzeit / Zeitzonen, auch wenn sie als solche gelten Wanduhren. Beide time und gettimeofday geben, zumindest heutzutage, Sekunden seit der Epoche zurück (auch bekannt als Unix-Zeitstempel). Dies ist unabhängig von Zeitzonen / DST. Schaltsekunden sind eine andere Geschichte…

    – Zulan

    7. Mai 2016 um 7:18 Uhr

  • Für Android-Benutzer kann die Verwendung von CLOCK_MONOTONIC problematisch sein, da die App möglicherweise zusammen mit der Uhr angehalten wird. Dafür hat Android den Timer ANDROID_ALARM_ELAPSED_REALTIME hinzugefügt, auf den über ioctl zugegriffen werden kann. Einige Informationen zu diesen und anderen Suspendierungsinformationen können gefunden werden hier

    – Itay Bianco

    11. Juli 2016 um 7:15 Uhr

Ciro Santilli Benutzeravatar von OurBigBook.com
Ciro Santilli OurBigBook.com

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.htmlund man clock_gettime besagt, 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, decken wir sie auch ab: http://en.cppreference.com/w/cpp/chrono

GCC 5.3.0 (C++ stdlib befindet sich in 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 vs CLOCK_MONOTONIC: Unterschied zwischen CLOCK_REALTIME und CLOCK_MONOTONIC?

  • Tolle Antwort, die die typischen Implementierungen entmystifiziert. Das müssen die Leute wirklich wissen.

    – Unendlich

    24. August 2018 um 21:56 Uhr

1425070cookie-checkZeit in Linux messen – Zeit vs. Uhr vs. getrusage vs. clock_gettime vs. gettimeofday vs. timespec_get?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy