2011-10-06 10 views
0

Comment puis-je calculer le temps d'exécution dans le code suivant:Comment calculer le temps d'exécution en C?

#include <stdio.h> /* Core input/output operations       */ 
#include <stdlib.h> /* Conversions, random numbers, memory allocation, etc. */ 
#include <math.h> /* Common mathematical functions      */ 
#include <time.h> /* Converting between various date/time formats   */ 
#include <sys/time.h> 
#define PI  3.1415926535 /* Known vaue of PI       */ 
#define NDARTS  128 /* Number of darts thrown     */ 
double pseudo_random(double a, double b) { 
double r; /* Random number */ 
r = ((b - a) * ((double) rand()/(double) RAND_MAX)) + a; 
return r; 
} 
int main (int argc, char *argv[]) { 
int n_procs,  /* Number of processors     */ 
llimit,  /* Lower limit for random numbers  */ 
ulimit,  /* Upper limit for random numbers  */ 
n_circle,  /* Number of darts that hit the circle */ 
i;    /* Dummy/Running index     */ 
double pi_sum,  /* Sum of PI values from each WORKER */ 
x,    /* x coordinate, betwen -1 & +1   */ 
y,    /* y coordinate, betwen -1 & +1   */ 
z,    /* Sum of x^2 and y^2     */ 
error;   /* Error in calculation of PI   */ 
clock_t start_time, /* Wall clock - start time    */ 
end_time;  /* Wall clock - end time    */ 
struct timeval stime, starttime1, endtime1; 
struct timeval tv1, tv2, diff; 

llimit = -1; 
ulimit = 1; 
n_circle = 0; 
printf("\n Monte Carlo method of finding PI\n\n"); 
printf(" Number of processors : %d\n", n_procs); 
printf(" Number of darts  : %d\n\n", NDARTS); 
gettimeofday(&tv1, NULL); 
gettimeofday(&stime, NULL); 
srand(stime.tv_usec * stime.tv_usec * stime.tv_usec * stime.tv_usec); 
for (i = 1; i <= NDARTS; i++) { 
x = pseudo_random(llimit, ulimit); 
y = pseudo_random(llimit, ulimit); 
z = pow(x, 2) + pow(y, 2); 
if (z <= 1.0) { 
    n_circle++; 
    } 
} 


pi_sum = 4.0 * (double)n_circle/(double)NDARTS; 
pi_sum = pi_sum/n_procs; 
error = fabs((pi_sum - PI)/PI) * 100; 
gettimeofday(&tv2, NULL); 
double timeval_subtract (result, x, y) 
{ 
result = ((double) x - (double) y)/(double)CLOCKS_PER_SEC; 
} 
double result1 = timeval_subtract(&diff, &tv1, &tv2); 
printf(" Known value of PI : %11.10f\n", PI); 
printf(" Average value of PI : %11.10f\n", pi_sum); 
printf(" Percentage Error  : %10.8f\n", error); 
printf(" Time : \n", clock()); 
printf(" Start Time : \n",&tv1); 
printf(" End Time :\n", &tv2); 
printf(" Time elapsed (sec) : \n", result1); 
return 0; 
} 

je fonction timeval_subtract et quand j'exécute le code, je suis arrivé:

Monte Carlo method of finding PI 

Number of processors : 16372 
Number of darts  : 128 

Known value of PI : 3.1415926535 
Average value of PI : 0.0002004184 
Percentage Error  : 99.99362048 
Time : 
Start Time : 
End Time : 
Time elapsed (sec) : 

D'abord, je ne pouvais pas trouver le erreur dans la recherche du nombre de processeurs (je dois obtenir 1 processeur).

Deuxième "qui est le point le plus important", Pourquoi l'heure, l'heure de début, l'heure de fin et le temps écoulés sont-ils vides?

+0

Je pense que vous voudrez peut-être envisager d'utiliser un profileur. – stdcall

+1

Veuillez activer les avertissements de votre compilateur. Il vous dira quel est le problème avec les impressions et la chose 'n_procs'. – Mat

+0

clock() ne mesure pas le temps que votre programme a utilisé pour exécuter, mais essaye de retourner les cycles d'horloge du CPU utilisé (normalement mesuré dans les tics ou les jiffies). Mais même si vous convertissez cette valeur en secondes (en la divisant par CLOCKS_PER_SEC, le résultat peut différer significativement du temps que le programme a réellement utilisé pour terminer.) Combien cela diffère dépend de ce que fait le programme. – alk

Répondre

1

Parce que vous n'avez pas des chaînes de format adéquat pour eux, vous avez besoin de quelque chose en commençant par un « % », comme:

printf(" Time :%d \n", clock()); 
1

n_procs est jamais initialisés, la 16372-valeur qui est imprimé arrive juste à être ce qui était auparavant sur la pile.

La bibliothèque standard C ne fournit pas de fonctionnalité pour interroger le nombre de processeurs ou les minuteurs hautes performances. Vous devrez donc rechercher d'autres moyens d'interrogation. Par exemple, les API POSIX et Windows offrent des fonctionnalités comme celle-ci.

Modifier: Voir Programmatically find the number of cores on a machine pour savoir comment initialiser n_procs. En voyant comment vous utilisez gettimeofday, vous êtes probablement sur un variant Unix; "n_procs = sysconf (_SC_NPROCESSORS_ONLN);" est probablement ce que vous voulez.

1

Essayez ceci:

printf(" Time : %lu\n", clock()); 
printf(" Start Time : %lds %ldus\n", tv1.tv_sec, tv1.tv_usec); 
printf(" End Time : %lds %ldus\n", tv2.tv_sec, tv2.tv_usec); 

Et pour:

double timeval_subtract (result, x, y) 

utiliser ce qui suit pour retourner la différence de temps en microsecondes:

long timeval_subtract (struct timeval * result, struct timeval * x, struct timeval * y) 
{ 
    long usec = x->tv_sec * 1000000L + x->tv_usec; 
    usec -= (y->tv_sec * 1000000L + y->tv_usec); 

    result->tv_sec = usec/1000000L; 
    result->tv_usec = usec % 1000000L; 

    return usec; 
} 

En fonction de la différence des deux dates x et y la valeur de retour de la fonction timeval_subtract (pas la valeur représentée par result!) Pourrait être faux, en raison d'un débordement.

En supposant un long est large 32bit ce débordement se produit avec des différences plus grandes que 4294s, pour une longue ayant 64bit (qui devrait être le cas une machine 64bit) le trop-plein whould se produisent après que beaucoup plus tard ... ;-)

+0

J'ai eu cette erreur erreur: attendu ')' avant '*' jeton dans la ligne: long timeval_subtract (timeval * résultat, timeval * x, timeval * y) –

+0

@NUM ONE: Sry, vient d'ajouter le 'struct' manquant . – alk

+0

@NUM ONE: exemple remplacé par une meilleure solution – alk

0

Je vais essayer ce qui suit:

int  timeval_subtract (struct timeval *result, struct timeval *x, struct timeval *y) { 

    if (x->tv_usec < y->tv_usec) { 
      int nsec = (y->tv_usec - x->tv_usec)/1000000 + 1; 
      y->tv_usec -= 1000000 * nsec; 
      y->tv_sec += nsec; 
    } 
    if (x->tv_usec - y->tv_usec > 1000000) { 
      int nsec = (x->tv_usec - y->tv_usec)/1000000; 
      y->tv_usec += 1000000 * nsec; 
      y->tv_sec -= nsec; 
    } 

    result->tv_sec = x->tv_sec - y->tv_sec; 
    result->tv_usec = x->tv_usec - y->tv_usec; 

    return x->tv_sec < y->tv_sec; 
} 

void Start (struct timeval *timer_profiling) { 
     if (timer_profiling == NULL) return; 
     gettimeofday (timer_profiling , NULL); 
     return; 
} 

void End (struct timeval *timer_profiling , char *msg) { 
     struct timeval res; 
     struct timeval now; 
     gettimeofday (&now , NULL); 

     if (msg == NULL)  return; 

     timeval_subtract (&res , &now , timer_profiling); 
     sprintf (msg , "[ %ld,%.3ld ms]" , res.tv_sec*1000 + (long)round(res.tv_usec/1000) , res.tv_usec - (long)round(res.tv_usec/1000)*1000); 

     return; 
} 

Démarrer (& s) conclu avec un timer_profiling alloué, puis récupérer le résultat dans une chaîne en appelant End (s &, cuir épais);

+0

La fonction timeval_subtract fournie dans la source OP ne fonctionnera pas. – alk

+0

Oh, oui, vous avez raison, ajouté une implémentation alternative. Merci d'avoir signalé! – SCO

+0

Et ça a marché ...? – alk