2010-10-15 15 views
24

Sto provando a misurare la durata di una funzione.Misurazione del tempo impiegato da una funzione: clock_gettime

Ho un piccolo problema: anche se sto cercando di essere preciso, e uso i punti mobili, ogni volta che stampo il mio codice usando% lf ottengo una delle due risposte: 1.000 ... o 0.000 .... Questo Mi porta a chiedermi se il mio codice è corretto:

#define BILLION 1000000000L; 

// Calculate time taken by a request 
struct timespec requestStart, requestEnd; 
clock_gettime(CLOCK_REALTIME, &requestStart); 
function_call(); 
clock_gettime(CLOCK_REALTIME, &requestEnd); 

// Calculate time it took 
double accum = (requestEnd.tv_sec - requestStart.tv_sec) 
    + (requestEnd.tv_nsec - requestStart.tv_nsec) 
/BILLION; 
printf("%lf\n", accum); 

La maggior parte di questo codice non è stata fatta da me. Questa pagina di esempio conteneva codice che illustrava l'uso di clock_gettime: http://www.users.pjwstk.edu.pl/~jms/qnx/help/watcom/clibref/qnx/clock_gettime.html

Qualcuno potrebbe, per favore, farmi sapere cosa non è corretto, o perché sto ricevendo solo valori interi, per favore?

La ringrazio molto,

Jary

+11

No, no, no: don' t dare nomi ai numeri. Usa la funzione che servono invece: '#define CLOCK_PRECISION 1000000000L/* un miliardo * /' – pmg

+9

@pmg: tangente pedanteria: direi che un nome come "CLOCK_PRECISION" sarebbe necessario solo se le unità non fossero chiare dal nome variabile. Nel caso precedente, è chiaro dal nome 'tv_nsec' che siamo in nanosecondi. Quindi 'NANOSECONDS_PER_SECOND' potrebbe essere appropriato, ma non è molto diverso dal semplice' BILLION'. –

risposta

22

Dividendo un numero intero da un intero produce un numero intero. Prova questo:

E non utilizzare un punto e virgola alla fine della riga. #define è una direttiva di preprocessore, non un'istruzione, e includendo il punto e virgola risultante in BILLION definito come 1000000000L;, che si interromperebbe se si tentasse di utilizzarlo nella maggior parte dei contesti. Sei stato fortunato perché lo hai usato alla fine di un'espressione e al di fuori di ogni parentesi.

+2

Grazie mille per il vostro aiuto. E grazie per avermi fatto conoscere il punto e virgola, è qualcosa che ho dimenticato. Grazie mille! – Jary

+0

Per motivi di prestazioni .. #define ONE_OVER_BILLION 1E-9 e utilizzare moltiplica. – linleno

9

(requestEnd.tv_nsec - requestStart.tv_nsec) è di tipo intero, ed è sempre inferiore a BILLION, quindi il risultato della divisione uno dall'altro in aritmetica intera sarà sempre 0. È necessario eseguire il cast del risultato della sottrazione ad es. double prima di fare il divario.

1

Si noti che (requestEnd.tv_nsec - requestStart.tv_nsec) può essere negativo, nel qual caso è necessario sottrarre 1 secondo dalla differenza tv_sec e aggiungere un miliardo alla differenza tv_nsec.

0

So che la domanda è stata postata molto tempo fa, ma non vedo ancora la risposta che suggerirebbe di "convertire" il tempo trascorso in nanosecondi (o millisecondi) e non in secondi come nel proprio esempio di codice.

Il frammento di codice di esempio per illustrare l'idea:

long accum = (requestEnd.tv_nsec - requestStart.tv_nsec) 
+ (requestEnd.tv_sec - requestStart.tv_sec) * BILLION; 

In questo modo si può evitare l'aritmetica, che può essere pesante per alcune piattaforme galleggianti ...

Problemi correlati