2010-10-15 4 views
24

J'essaie de mesurer la durée d'une fonction.Temps de mesure pris par une fonction: clock_gettime

J'ai un petit problème: bien que j'essaie d'être précis, et j'utilise des points flottants, chaque fois que j'imprime mon code en utilisant% lf, j'obtiens une des deux réponses: 1.000 ... ou 0.000 .... me conduit à me demander si mon code est correct:

#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 plupart de ce code n'a pas été faite par moi. Cette page d'exemple avait un code illustrant l'utilisation de clock_gettime:

Quelqu'un peut-il me faire savoir ce qui est incorrect, ou pourquoi je ne reçois des valeurs entières s'il vous plaît?

Merci beaucoup,

Jary

+11

Non, non, non: don » t donner des noms aux nombres. Utilisez la fonction qu'ils servent à la place: '#define CLOCK_PRECISION 1000000000L/* un milliard * /' – pmg

+9

@pmg: Tangente de pédanterie: Je dirais qu'un nom tel que 'CLOCK_PRECISION' ne serait nécessaire que si les unités n'étaient pas claires à partir du Nom de variable. Dans le cas ci-dessus, il est clair d'après le nom 'tv_nsec' que nous sommes en nanosecondes. Donc 'NANOSECONDS_PER_SECOND' pourrait être approprié, mais ce n'est vraiment pas très différent de 'BILLION'. –

Répondre

22

un entier divisant par un entier donne un entier. Essayez ceci:

#define BILLION 1E9 

N'utilisez pas de point-virgule à la fin de la ligne. #define est une directive de préprocesseur, pas une instruction, et en incluant le point-virgule, BILLION est défini comme étant 1000000000L;, ce qui se casserait si vous essayiez de l'utiliser dans la plupart des contextes. Vous avez eu de la chance parce que vous l'avez utilisé à la toute fin d'une expression et hors des parenthèses.

+2

Merci beaucoup pour votre aide. Et merci de m'avoir informé sur le point-virgule, c'est quelque chose que j'ai oublié. Merci beaucoup! – Jary

+0

Par souci de performance .. #define ONE_OVER_BILLION 1E-9 et multipliez. – linleno

9

(requestEnd.tv_nsec - requestStart.tv_nsec) est de type entier et est toujours inférieur à BILLION, de sorte que le résultat de la division un par l'autre en arithmétique entière aura toujours 0. Vous devez convertir le résultat de la soustraction par ex. double avant de faire la division.

1

Notez que (requestEnd.tv_nsec - requestStart.tv_nsec) peut être négatif, auquel cas vous devez soustraire 1 seconde de la différence tv_sec et ajouter un milliard à la différence tv_nsec.

0

Je sais que la question a été postée depuis longtemps, mais je ne vois toujours pas la réponse qui vous suggérerait de "convertir" le temps écoulé en nanosecondes (ou millisecondes) et non en secondes comme dans votre exemple de code.

Le fragment de code exemple pour illustrer l'idée:

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

De cette façon, vous pouvez éviter l'arithmétique en virgule flottante, qui peut être lourd pour certaines plates-formes ...

Questions connexes