287 votes

Temps d'exécution du programme C

J'ai un programme en C qui a pour but d'être exécuté en parallèle sur plusieurs processeurs. Je dois être en mesure d'enregistrer le temps d'exécution (qui peut aller de 1 seconde à plusieurs minutes). J'ai cherché des réponses, mais elles semblent toutes suggérer d'utiliser la fonction clock() qui consiste alors à calculer le nombre d'horloges qu'a pris le programme divisé par le nombre d'heures d'utilisation de la fonction Clocks_per_second valeur.

Je ne suis pas sûr de savoir comment le Clocks_per_second est calculée ?

En Java, je prends simplement le temps actuel en millisecondes avant et après l'exécution.

Existe-t-il une chose similaire en C ? J'ai regardé, mais je n'arrive pas à trouver un moyen d'obtenir quelque chose de mieux qu'une seconde résolution.

Je suis également conscient qu'un profileur serait une option, mais je cherche à mettre en œuvre une minuterie moi-même.

Gracias

4 votes

Quels sont les cadres OS/API que vous utilisez/disponibles ? Simplement du C ?

6 votes

Il s'agit d'un programme assez petit, juste un simple C

2 votes

J'ai écrit en détail sur la mise en œuvre d'une solution portable dans cette réponse : stackoverflow.com/questions/361363/

443voto

Thomas Pornin Points 36984

CLOCKS_PER_SEC est une constante qui est déclarée dans <time.h> . Pour obtenir le temps CPU utilisé par une tâche dans une application C, utilisez :

clock_t begin = clock();

/* here, do your time-consuming job */

clock_t end = clock();
double time_spent = (double)(end - begin) / CLOCKS_PER_SEC;

Notez que cela renvoie le temps sous la forme d'un type à virgule flottante. Cela peut être plus précis qu'une seconde (par exemple, vous mesurez 4,52 secondes). La précision dépend de l'architecture ; sur les systèmes modernes, vous obtenez facilement 10 ms ou moins, mais sur les anciennes machines Windows (de l'ère Win98), elle était plus proche de 60 ms.

clock() est le standard C ; il fonctionne "partout". Il existe des fonctions spécifiques au système, telles que getrusage() sur les systèmes de type Unix.

Java System.currentTimeMillis() ne mesure pas la même chose. C'est une "horloge murale" : elle peut vous aider à mesurer le temps qu'il a fallu au programme pour s'exécuter, mais elle ne vous dit pas combien de temps CPU a été utilisé. Sur un système multitâche (c'est-à-dire tous les systèmes), ces chiffres peuvent être très différents.

1 votes

Il me donne un résultat très aléatoire - j'obtiens un mélange de grand/petit/nombre négatif sur le même morceau de code. GCC 4.7 Linux 3.2 AMD64

1 votes

Cela donne le temps en secondes ?

3 votes

Oui : clock() renvoie un temps dans une certaine échelle interne appelée "horloges", et CLOCKS_PER_SEC est le nombre d'horloges par seconde, donc en divisant par CLOCKS_PER_SEC donne un temps en secondes. Dans le code ci-dessus, la valeur est un double pour que vous puissiez le mettre à l'échelle à volonté.

139voto

S..K Points 524

Si vous utilisez le shell Unix pour l'exécution, vous pouvez utiliser la commande time.

en faisant

$ time ./a.out

en supposant que a.out est l'exécutable, vous obtiendrez le temps nécessaire à l'exécution de cette opération.

4 votes

@acgtyrant mais seulement pour les programmes simples, car cela prendra tout le temps du programme, y compris l'entrée, la sortie, etc.

2 votes

Si vous êtes sous Linux, et que vous avez réduit votre (micro)benchmark à un programme avec une charge de démarrage négligeable, par exemple un exécutable statique qui exécute votre boucle chaude pendant quelques secondes, vous pouvez utiliser perf stat ./a.out pour obtenir des compteurs de performance HW pour les manques de cache et les erreurs de prédiction de branche, et IPC.

109voto

Alexandre C. Points 31758

A la vanille ordinaire C :

#include <time.h>
#include <stdio.h>

int main()
{
    clock_t tic = clock();

    my_expensive_function_which_can_spawn_threads();

    clock_t toc = clock();

    printf("Elapsed: %f seconds\n", (double)(toc - tic) / CLOCKS_PER_SEC);

    return 0;
}

54 votes

Les meilleurs noms de variables que j'ai vus depuis longtemps. tic = "time in clock", toc = "time out clock". Mais aussi tic-toc = "tick-tock". C'est comme ça que je vais étiqueter les prises de temps à partir de maintenant.

79voto

Wes Hardaker Points 10426

Vous voulez fonctionnellement ceci :

#include <sys/time.h>

struct timeval  tv1, tv2;
gettimeofday(&tv1, NULL);
/* stuff to do! */
gettimeofday(&tv2, NULL);

printf ("Total time = %f seconds\n",
         (double) (tv2.tv_usec - tv1.tv_usec) / 1000000 +
         (double) (tv2.tv_sec - tv1.tv_sec));

Notez que cette mesure s'effectue en microsecondes, et pas seulement en secondes.

2 votes

Le compilateur MinGW est basé sur GCC. Il fonctionnera donc avec lui. Mais si vous utilisez le compilateur Visual C, vous obtiendrez une erreur.

11 votes

Oui, cela fonctionnera sous Windows avec une bibliothèque c qui supporte l'appel gettimeofday. En fait, le compilateur n'a pas d'importance, vous devez juste le lier à une bibliothèque libc décente. Ce qui, dans le cas de mingw, n'est pas la bibliothèque par défaut de Windows.

1 votes

Cela fonctionne pour moi sur Windows XP avec cygwin gcc et Linux Ubuntu. C'est exactement ce que je voulais.

13voto

Aditya Mohan Points 61

La plupart des programmes simples ont un temps de calcul en milli-secondes. Donc, je suppose que vous trouverez cela utile.

#include <time.h>
#include <stdio.h>

int main(){
    clock_t start = clock();
    // Execuatable code
    clock_t stop = clock();
    double elapsed = (double)(stop - start) * 1000.0 / CLOCKS_PER_SEC;
    printf("Time elapsed in ms: %f", elapsed);
}

Si vous voulez calculer le temps d'exécution de l'ensemble du programme et que vous êtes sur un système Unix, exécutez votre programme à l'aide de la commande temps comme ceci time ./a.out

0 votes

Dans Windows au moins, le facteur est d'au moins 100 mais pas de 1000 et il n'est pas exact.

6 votes

Cette réponse n'ajoute rien qui n'était pas dans Alexandre C 's réponse de deux ans plus tôt.

6 votes

@boctulus : 1s est siempre 1000ms, également sous Windows.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X