2012-09-12 31 views
114

Tra le funzioni di temporizzazione, time, clockgetrusage, clock_gettime, gettimeofday e timespec_get, voglio capire chiaramente come la loro applicazione e quali sono i loro valori di ritorno in modo da sapere in quale situazione devo usarli.Misurare il tempo in Linux - tempo vs orologio vs getrusage vs clock_gettime vs gettimeofday vs timespec_get?

In primo luogo abbiamo bisogno di classificare funzioni che restituiscono muro-clock valori confronta con funzioni che restituiscono processo o thread valori. gettimeofday restituisce il valore di orologio a muro, clock_gettime restituisce il valore di orologio a parete o il valore di processo o i valori di thread a seconda del parametro Clock passato ad esso. getrusage e clock valori di processo di ritorno.

Quindi la seconda domanda riguarda l'implementazione di queste funzioni e, di conseguenza, la loro accuratezza. Quale meccanismo hardware o software utilizza queste funzioni.

Sembra che getrusage utilizzi solo il segno di spunta del kernel (in genere lungo 1 ms) e di conseguenza non può essere più preciso del ms. È giusto? Quindi la funzione getimeofday sembra utilizzare l'hardware sottostante più preciso disponibile. Di conseguenza, la precisione è solitamente il microsecondo (non può essere più a causa dell'API) sull'hardware recente. E a proposito di clock, la pagina man parla di "approssimazione", cosa significa? Che dire di clock_gettime, l'API è in nanosecondi, vuol dire che è in grado di essere così preciso se l'hardware sottostante lo consente? Che dire della monotonicità?

Esistono altre funzioni?

risposta

150

Il problema è che sono disponibili diverse funzioni temporali in C e C++ e alcune di esse variano nel comportamento tra le implementazioni. Ci sono anche molte mezze risposte in giro. Compilare un elenco di funzioni di orologio insieme alle loro proprietà avrebbe risposto correttamente alla domanda. Per iniziare chiediamo quali sono le proprietà rilevanti che stiamo cercando. Osservando il tuo post, suggerisco:

  • Che ora viene misurata dall'orologio? (reale, utente, sistema o, si spera, non orologio da parete?)
  • Qual è la precisione dell'orologio? (s, ms, μs, o più veloce?)
  • Dopo quanto tempo si avvolge l'orologio? O c'è qualche meccanismo per evitarlo?
  • L'orologio è monotono o cambierà con i cambiamenti nell'ora del sistema (tramite NTP, fuso orario, ora legale, dall'utente, ecc.)?
  • In che modo le indicazioni sopra variano tra le implementazioni?
  • La funzione specifica è obsoleta, non standard, ecc.?

Prima di iniziare la lista, vorrei far notare che il tempo muro-clock è raramente il momento giusto per utilizzare, mentre cambia con i cambiamenti di fuso orario, le modifiche dell'ora legale, o se l'orologio da parete è sincronizzato da NTP. Nessuna di queste cose è utile se si utilizza il tempo per pianificare eventi o per eseguire il benchmark delle prestazioni. È davvero buono solo per quello che dice il nome, un orologio sul muro (o sul desktop).

Ecco quello che ho trovato finora per orologi in Linux e OS X:

  • time() restituisce il tempo di muro-clock dal sistema operativo, con precisione in pochi secondi.
  • clock() sembra restituire la somma di utente e ora di sistema. È presente nella C89 e successive. Un tempo questo doveva essere il tempo della CPU in cicli, ma gli standard moderni like POSIX richiedono CLOCKS_PER_SEC per essere 1000000, dando una precisione massima possibile di 1 μs. La precisione sul mio sistema è infatti di 1 μs. Questo orologio si avvolge una volta terminato (ciò accade normalmente dopo ~ 2^32 tick, che non è molto lungo per un orologio da 1 MHz). man clock dice che poiché glibc 2.18 è implementato con clock_gettime(CLOCK_PROCESS_CPUTIME_ID, ...) in Linux.
  • clock_gettime(CLOCK_MONOTONIC, ...) fornisce una risoluzione di nanosecondi, è monotona. Credo che i "secondi" e i "nanosecondi" siano memorizzati separatamente, ciascuno in contatori a 32 bit. Quindi, qualsiasi avvolgimento si sarebbe verificato dopo molte dozzine di anni di operatività. Questo sembra un ottimo orologio, ma sfortunatamente non è ancora disponibile su OS X. POSIX 7 describes CLOCK_MONOTONIC as an optional extension.
  • getrusage() si è rivelata la scelta migliore per la mia situazione. Riporta separatamente gli orari dell'utente e del sistema e non si avvolge. La precisione del mio sistema è di 1 μs, ma l'ho anche testata su un sistema Linux (Red Hat 4.1.2-48 con GCC 4.1.2) e lì la precisione era solo di 1 ms.
  • gettimeofday() restituisce l'ora del wall-clock con precisione (nominale) μs. Sul mio sistema questo orologio sembra avere precisione μ, ma questo non è garantito, perché "the resolution of the system clock is hardware dependent". POSIX.1-2008 says that. "Le applicazioni devono utilizzare la funzione clock_gettime() invece della funzione obsoleta gettimeofday()", quindi è necessario stare lontani da esso. Linux x86 e lo implementa as a system call.
  • mach_absolute_time() è un'opzione per la temporizzazione ad altissima risoluzione (ns) su OS X. Sul mio sistema, questo effettivamente fornisce risoluzione ns. In linea di principio questo orologio si avvolge, tuttavia sta memorizzando ns usando un numero intero senza segno a 64 bit, quindi l'involucro non dovrebbe essere un problema nella pratica. La portabilità è discutibile.
  • I wrote a hybrid function sulla base di this snippet che clock_gettime utilizza quando compilato su Linux, o di un timer Mach quando compilato su OS X, al fine di ottenere ns precisione sia su Linux e OS X.

Tutto quanto sopra esiste in sia Linux che OS X tranne dove diversamente specificato. "Il mio sistema" di cui sopra è un Apple che esegue OS X 10.8.3 con GCC 4.7.2 da MacPorts.

Infine, ecco un elenco di riferimenti che ho trovato utile in aggiunta ai link di cui sopra:


Aggiornamento: per OS X, clock_gettime è stato implementato a partire da 10.12 (Sierra). Inoltre, entrambe le piattaforme basate su POSIX e BSD (come OS X) condividono il campo struct rusage.ru_utime.

+1

ora avete 18 punti rep ;-) –

+0

Mac OS X non ha 'clock_gettime', da qui l'uso di [ 'gettimeofday()'] (http://www.songho.ca/misc/timer/timer.html) è un po 'più versatile di 'clock_gettime()' – bobobobo

+0

@bobobobo Sono d'accordo che OS X non ha clock_gettime (), tuttavia gettimeofday() purtroppo misura l'ora dell'orologio a muro. Ho aggiornato il mio post per fornire queste informazioni. Se la precisione di ms è sufficiente, allora suggerisco getrusage() come miglior orologio da usare come timer. –

12

C11 esempio timespec_get

Uso in: https://stackoverflow.com/a/36095407/895245

La massima precisione in risposta è nanosecondi, ma la precisione effettiva implementazione è definito e può essere inferiore.

Restituisce il tempo di parete, non l'utilizzo della CPU.

glibc 2.21 implementa sotto sysdeps/posix/timespec_get.c e in avanti direttamente a:

clock_gettime (CLOCK_REALTIME, ts) < 0) 

clock_gettime e CLOCK_REALTIME sono POSIX http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_getres.html, e man clock_gettime dice che questa misura possa avere discontinuità se si cambia l'impostazione, mentre i vostri programma viene eseguito un certo tempo di sistema .

C++ 11 crono

Dato che ci siamo, diamo loro coprire così: http://en.cppreference.com/w/cpp/chrono

GCC 5.3.0 (C++ stdlib è fonte interna GCC):

  • high_resolution_clock è un alias per system_clock
  • system_clock inoltra al primo dei seguenti disponibili:
    • clock_gettime(CLOCK_REALTIME, ...)
    • gettimeofday
    • time
  • steady_clock inoltra al primo dei seguenti disponibili:
    • clock_gettime(CLOCK_MONOTONIC, ...)
    • system_clock

Chiesto a: Difference between std::system_clock and std::steady_clock?

CLOCK_REALTIME vs CLOCK_MONOTONIC: Difference between CLOCK_REALTIME and CLOCK_MONOTONIC?

+1

Grazie per l'aggiunta. –

Problemi correlati