GNU/Linux >> Znalost Linux >  >> Linux

Změřte čas v Linuxu - čas vs hodiny vs getrusage vs clock_gettime vs gettimeofday vs timespec_get?

Problém je v tom, že v C a C++ je k dispozici několik různých časových funkcí a některé z nich se liší v chování mezi implementacemi. Kolem je také spousta polovičních odpovědí. Sestavení seznamu hodinových funkcí spolu s jejich vlastnostmi by správně odpovědělo na otázku. Pro začátek se zeptejme, jaké jsou relevantní vlastnosti, které hledáme. Při pohledu na váš příspěvek navrhuji:

  • Jaký čas měří hodiny? (skutečné, uživatelské, systémové nebo, doufejme, že ne, nástěnné hodiny?)
  • Jaká je přesnost hodin? (s, ms, µs nebo rychlejší?)
  • Po jaké době se hodiny obtáčí? Nebo existuje nějaký mechanismus, jak se tomu vyhnout?
  • Jsou hodiny monotónní, nebo se budou měnit se změnami systémového času (prostřednictvím NTP, časového pásma, letního času, uživatelem atd.)?
  • Jak se výše uvedené liší mezi implementacemi?
  • Je konkrétní funkce zastaralá, nestandardní atd.?

Než začnu seznam, rád bych zdůraznil, že čas nástěnných hodin je zřídka tím správným časem k použití, zatímco se mění se změnami časového pásma, změnou letního času nebo pokud jsou nástěnné hodiny synchronizovány pomocí NTP. Žádná z těchto věcí není dobrá, pokud čas využíváte k plánování událostí nebo ke srovnávání výkonu. Je to opravdu dobré pouze pro to, co říká název, hodiny na stěně (nebo na ploše).

Zde je to, co jsem zatím našel pro hodiny v Linuxu a OS X:

  • time() vrátí čas nástěnných hodin z operačního systému s přesností v sekundách.
  • clock() Zdá se, že vrací součet času uživatele a systému. Je přítomen v C89 a novějších. Kdysi to měl být čas CPU v cyklech, ale moderní standardy jako POSIX vyžadují, aby CLOCKS_PER_SEC bylo 1000000, což dává maximální možnou přesnost 1 µs. Přesnost na mém systému je skutečně 1 µs. Tyto hodiny se zalomí, jakmile se vyčerpají (k tomu obvykle dochází po ~2^32 tikáních, což není příliš dlouho pro hodiny 1 MHz). man clock říká, že od glibc 2.18 je implementován s clock_gettime(CLOCK_PROCESS_CPUTIME_ID, ...) v Linuxu.
  • clock_gettime(CLOCK_MONOTONIC, ...) poskytuje nanosekundové rozlišení, je monotónní. Věřím, že „sekundy“ a „nanosekundy“ jsou uloženy odděleně, každá v 32bitových čítačích. K jakémukoli zalomení by tedy došlo po mnoha desítkách let provozuschopnosti. Vypadá to jako velmi dobré hodiny, ale bohužel ještě nejsou dostupné na OS X. POSIX 7 popisuje CLOCK_MONOTONIC jako volitelné rozšíření.
  • getrusage() se pro mou situaci ukázalo jako nejlepší volba. Hlásí uživatelské a systémové časy odděleně a nezalamuje se. Přesnost na mém systému je 1 µs, ale testoval jsem to také na systému Linux (Red Hat 4.1.2-48 s GCC 4.1.2) a tam byla přesnost pouze 1 ms.
  • gettimeofday() vrátí čas nástěnných hodin s (nominálně) µs přesností. Na mém systému se zdá, že tyto hodiny mají přesnost µs, ale není to zaručeno, protože "rozlišení systémových hodin je závislé na hardwaru". POSIX.1-2008 to říká. "Aplikace by měly používat clock_gettime() místo zastaralé funkce gettimeofday() funkce", takže byste se od ní měli držet dál. Linux x86 a implementuje ji jako systémové volání.
  • mach_absolute_time() je volba pro velmi vysoké rozlišení (ns) časování v OS X. V mém systému to skutečně dává rozlišení ns. V principu se tyto hodiny obtáčí, nicméně ukládají ns pomocí 64bitového celého čísla bez znaménka, takže s obtékáním by v praxi neměl být problém. Přenositelnost je sporná.
  • Napsal jsem hybridní funkci založenou na tomto úryvku, která používá clock_gettime při kompilaci v Linuxu nebo Mach timer při kompilaci v OS X, abych dosáhla přesnosti ns v Linuxu i OS X.

Všechny výše uvedené existují v Linuxu i OS X, pokud není uvedeno jinak. "Můj systém" ve výše uvedeném je Apple se systémem OS X 10.8.3 s GCC 4.7.2 z MacPorts.

Nakonec zde je seznam odkazů, které mi kromě výše uvedených odkazů pomohly:

  • http://blog.habets.pp.se/2010/09/gettimeofday-should-never-be-used-to-measure-time
  • Jak změřit SKUTEČNOU dobu provádění programu C pod Linuxem?
  • http://digitalsandwich.com/archives/27-benchmarking-misconceptions-microtime-vs-getrusage.html
  • http://www.unix.com/hp-ux/38937-getrusage.html

Aktualizovat :pro OS X, clock_gettime byla implementována od 10.12 (Sierra). Také platformy založené na POSIX a BSD (jako OS X) sdílejí rusage.ru_utime struct pole.


C11 timespec_get

Příklad použití na:https://stackoverflow.com/a/36095407/895245

Maximální možná vrácená přesnost je nanosekundy, ale skutečná přesnost je definována implementací a mohla by být menší.

Vrací čas zdi, nikoli využití CPU.

glibc 2.21 jej implementuje pod sysdeps/posix/timespec_get.c a přeposílá přímo na:

clock_gettime (CLOCK_REALTIME, ts) < 0)

clock_gettime a CLOCK_REALTIME jsou POSIX http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_getres.html a man clock_gettime říká, že toto opatření může mít nespojitosti, pokud změníte některé nastavení systémového času během běhu programu.

C++ 11 chrono

Když už jsme u toho, pojďme se jim věnovat také:http://en.cppreference.com/w/cpp/chrono

GCC 5.3.0 (C++ stdlib je ve zdroji GCC):

  • high_resolution_clock je alias pro system_clock
  • system_clock přesměruje na první z následujících dostupných:
    • clock_gettime(CLOCK_REALTIME, ...)
    • gettimeofday
    • time
  • steady_clock přesměruje na první z následujících dostupných:
    • clock_gettime(CLOCK_MONOTONIC, ...)
    • system_clock

Dotaz na:Rozdíl mezi std::system_clock a std::steady_clock?

CLOCK_REALTIME vs CLOCK_MONOTONIC :Rozdíl mezi CLOCK_REALTIME a CLOCK_MONOTONIC?


Linux
  1. 7 Linux hwclock Příklady příkazů pro nastavení hardwarových hodin Date Time

  2. Příklady příkazů timedatectl v Linuxu

  3. Příklady příkazů uptime v Linuxu

  1. Stavy procesu Linuxu

  2. Kompilace C++ na vzdáleném linuxovém stroji – upozornění na zkreslení hodin

  3. Jak Linux používá hodiny reálného času?

  1. Rychlejší spouštění Linuxu

  2. Linux – Jak změřit čas, kdy dorazí paket?

  3. Linux – jak měřit a předcházet posunu hodin?