2012-06-16 12 views
16

Voglio misurare il tempo di esecuzione del mio codice C++. L'esecuzione del mio codice richiede circa 12 ore e voglio scrivere questa volta alla fine dell'esecuzione del mio codice. Come posso farlo nel mio codice?Misurazione del runtime di un codice C++?

Sistema operativo: Linux

+1

In quale sistema operativo è in esecuzione il codice? –

+0

Mi piace profilare più codici contemporaneamente. – Puppy

+1

basta usare il comando 'time' quando si avvia qualunque programma. – Jasen

risposta

7

Ho usato qualcosa di simile in uno dei miei progetti:

#include <sys/time.h> 

struct timeval start, end; 
gettimeofday(&start, NULL); 
//Compute 
gettimeofday(&end, NULL); 
double elapsed = ((end.tv_sec - start.tv_sec) * 1000) 
     + (end.tv_usec/1000 - start.tv_usec/1000); 

Questo è per millisecondi e funziona sia per la C e C++.

54

Se si utilizza C++ 11 è possibile utilizzare system_clock::now():

auto start = std::chrono::system_clock::now(); 

/* do some work */ 

auto end = std::chrono::system_clock::now(); 
auto elapsed = end - start; 
std::cout << elapsed.count() << '\n'; 

è anche possibile specificare la granularità da utilizzare per la rappresentazione di una durata:

// this constructs a duration object using milliseconds 
auto elapsed = 
    std::chrono::duration_cast<std::chrono::milliseconds>(end - start); 

// this constructs a duration object using seconds 
auto elapsed = 
    std::chrono::duration_cast<std::chrono::seconds>(end - start); 

Se non è possibile utilizzare C + +11, quindi dai uno sguardo a chrono da Boost.

La cosa migliore dell'utilizzo di tali librerie standard è che la loro portabilità è veramente alta (ad esempio, funzionano entrambi in Linux e Windows). Quindi non è necessario preoccuparsi troppo se in seguito si decide di eseguire il porting dell'applicazione.

Queste librerie seguono anche un moderno design C++, al contrario degli approcci di tipo C.

MODIFICA: L'esempio precedente può essere utilizzato per misurare wall-clock time. Questo non è, tuttavia, l'unico modo per misurare il tempo di esecuzione di un programma. In primo luogo, possiamo distinta tra utente e sistema di tempo:

  • time Utente: Il tempo speso dal programma in esecuzione in user space.
  • Ora di sistema: Il tempo trascorso dal programma in esecuzione nello spazio di sistema (o kernel). Un programma entra nello spazio del kernel, ad esempio quando si esegue un system call.

A seconda degli obiettivi, può essere necessario o non considerare l'ora del sistema come parte del tempo di esecuzione di un programma. Ad esempio, se l'obiettivo è misurare semplicemente l'ottimizzazione del compilatore sul codice utente, è probabilmente meglio lasciare il tempo di sistema. D'altra parte, se l'utente desidera determinare se le chiamate di sistema sono un sovraccarico significativo, è necessario misurare anche l'ora del sistema.

Inoltre, poiché la maggior parte dei sistemi moderni è time-shared, diversi programmi possono competere per diverse risorse di elaborazione (ad es. CPU). In tal caso, un'altra distinzione può essere fatta:

  • Wall-clock time: Utilizzando tempo orologio a muro l'esecuzione del programma viene misurato nello stesso modo come se stessimo usando un orologio (parete) esterna. Questo approccio non considera l'interazione tra i programmi.
  • CPU time: In questo caso contiamo solo il tempo in cui un programma è effettivamente in esecuzione sulla CPU.Se un programma (P1) è co-programmato con un altro (P2), e vogliamo ottenere il tempo CPU per P1, questo approccio non include il tempo mentre P2 è in esecuzione e P1 è in attesa della CPU (al contrario di l'approccio all'orologio a muro).

per misurare il tempo di CPU, Boost include un set of extra clocks:

  • process_real_cpu_clock, cattura il tempo di CPU orologio da parete speso dal processo in corso.
  • process_user_cpu_clock, cattura il tempo della CPU utente trascorso dal processo corrente.
  • process_system_cpu_clock, cattura il tempo della CPU del sistema trascorso dal processo corrente. Una classe simile a una tupla process_cpu_clock, che cattura insieme i tempi di elaborazione reali, della CPU utente e della CPU di sistema.
  • A thread_clock thread clock costante che fornisce il tempo trascorso dal thread corrente (quando supportato da una piattaforma).

Sfortunatamente, C++ 11 non ha tali orologi. Ma Boost è una libreria ampiamente utilizzata e, probabilmente, questi orologi aggiuntivi saranno incorporati in C++ 1x ad un certo punto. Quindi, se usi Boost, sarai pronto quando il nuovo standard C++ li aggiungerà.

Infine, se si desidera misurare il tempo impiegato da un programma per eseguire dalla riga di comando (anziché aggiungere del codice al programma), è possibile dare un'occhiata al comando time, proprio come suggerisce @ BЈовић. Questo approccio, tuttavia, non consente di misurare singole parti del programma (ad es. Il tempo necessario per l'esecuzione di una funzione).

+0

la mia domanda è: che ne dici di differenze C++/C++ 11 e librerie boost? – gaussblurinc

+1

@loldop Credo che l'implementazione C++ 11 sia un sottoinsieme della libreria Boost chrono. Quindi dovrebbero avere un'API molto simile (se non la stessa). Il vantaggio di usare il C++ 11 è che non è necessario usare Boost (se chrono è l'unica libreria che vuoi da Boost). – betabandido

10

È possibile utilizzare time per avviare il programma. Al termine, stampa statistiche gradevoli sull'esecuzione del programma. È facile configurare cosa stampare. Per impostazione predefinita, stampa i tempi di utente e CPU necessari per eseguire il programma.

EDIT: Prendere una nota che ogni misura dal codice non è corretto, perché l'applicazione sarà ottenere bloccato da altri programmi, quindi, si dà valori errati *.

* Con valori sbagliati, volevo dire che è facile da ottenere il tempo necessario per eseguire il programma, ma che il tempo varia a seconda del carico di CPU durante l'esecuzione del programma. Per ottenere una misurazione del tempo relativamente stabile, che non dipende dal carico della CPU, è possibile eseguire l'applicazione utilizzando time e utilizzare la CPU come risultato della misurazione.

+1

Penso che il blocco sia anche una parte del tempo di esecuzione del programma, no? –

+1

@EitanT No, perché il carico della CPU (s) cambia. Il carico corrente non deve essere lo stesso del carico in 1 ora o domani. –

+0

Ora capisco cosa intendi. –

16

Utilizzare std::chrono::steady_clock e non std::chrono::system_clock per misurare il tempo di esecuzione in C++ 11. La ragione è (citando documentazione system_clock 's):

sulla maggior parte dei sistemi, il tempo di sistema può essere regolato in qualsiasi momento

mentre steady_clock è monotona ed è più adatto per cadenze di misurazione:

Classe std :: chrono :: steady_clock rappresenta un orologio monotono. L'ora di punti di questo orologio non può diminuire mentre il tempo fisico si sposta in avanti. Questo orologio non è correlato all'orario dell'orologio da parete ed è più adatto per gli intervalli di misurazione .

Ecco un esempio:

auto start = std::chrono::steady_clock::now(); 
// do something 
auto finish = std::chrono::steady_clock::now(); 
double elapsed_seconds = std::chrono::duration_cast< 
    std::chrono::duration<double> >(finish - start).count(); 

Un piccolo consiglio pratico: se si sta misurando fase di esecuzione e di voler segnalare il secondo std::chrono::duration_cast<std::chrono::seconds> raramente è quello che ti serve perché ti dà intero numero di secondi. Per ottenere il tempo in secondi come double utilizzare l'esempio sopra.

+0

Non ho avuto la mancia pratica. Non è 'std :: chrono :: duration_cast ' il modo per ottenere la differenza tra due punti di tempo come secondi totali? – Isaac

+0

@Isaac Ciò che intendo è che 'std :: chrono :: duration_cast ' restituirà 0 se la differenza è inferiore a un secondo. Se vuoi la durata come numero in virgola mobile, usa 'double' invece di' seconds'. – vitaut

0

Si potrebbe anche provare alcune classi di timer che si avviano e si arrestano automaticamente e raccogliere statistiche sul tempo medio, massimo e minimo trascorso in qualsiasi blocco di codice, nonché il numero di chiamate. Queste classi cxx-rtimer sono disponibili su GitHub e offrono supporto per l'utilizzo di std :: chrono, clock_gettime() o boost :: posix_time come sorgente di clock back-end.

Con questi timer, si può fare qualcosa di simile:

void timeCriticalFunction() { 
    static rtimers::cxx11::DefaultTimer timer("expensive"); 
    auto scopedStartStop = timer.scopedStart(); 
    // Do something costly... 
} 

con tempismo statistiche scritte a std :: cerr al termine del programma.

Problemi correlati