80 votes

Meilleure méthode de synchronisation en C ?

Quelle est la meilleure façon de chronométrer une section de code avec une haute résolution et une bonne portabilité ?

/* Time from here */
ProcessIntenseFunction();
/* to here. */

printf("Time taken %d seconds %d milliseconds", sec, msec);

Existe-t-il une bibliothèque standard qui offrirait une solution multiplateforme ?

135voto

Ben Alpert Points 30381

Je pense que ça devrait marcher :

#include <time.h>

clock_t start = clock(), diff;
ProcessIntenseFunction();
diff = clock() - start;

int msec = diff * 1000 / CLOCKS_PER_SEC;
printf("Time taken %d seconds %d milliseconds", msec/1000, msec%1000);

21voto

Mark Harrison Points 77152

Gettimeofday() fera probablement ce que vous voulez.

Si vous êtes sur du matériel Intel, voici comment lire le compteur d'instructions en temps réel du CPU. Il vous indiquera le nombre de cycles du CPU exécutés depuis le démarrage du processeur. Il s'agit probablement du compteur le plus fin et le moins coûteux que vous puissiez obtenir pour mesurer les performances.

Notez qu'il s'agit du nombre de cycles du CPU. Sous linux, vous pouvez obtenir la vitesse du CPU à partir de /proc/cpuinfo et la diviser pour obtenir le nombre de secondes. Convertir ce nombre en double est assez pratique.

Quand j'exécute ceci sur ma boîte, j'obtiens

11867927879484732
11867927879692217
it took this long to call printf: 207485

Voici le Guide du développeur Intel qui donne des tonnes de détails.

#include <stdio.h>
#include <stdint.h>

inline uint64_t rdtsc() {
    uint32_t lo, hi;
    __asm__ __volatile__ (
      "xorl %%eax, %%eax\n"
      "cpuid\n"
      "rdtsc\n"
      : "=a" (lo), "=d" (hi)
      :
      : "%ebx", "%ecx");
    return (uint64_t)hi << 32 | lo;
}

main()
{
    unsigned long long x;
    unsigned long long y;
    x = rdtsc();
    printf("%lld\n",x);
    y = rdtsc();
    printf("%lld\n",y);
    printf("it took this long to call printf: %lld\n",y-x);
}

4voto

tvanfosson Points 268301

gettimeofday retournera un temps précis à la microseconde près dans la résolution de l'horloge du système. Vous pouvez également consulter la page Temporisateurs haute résolution sur SourceForge.

3voto

driAn Points 1973

J'utilise SDL_GetTicks de la Bibliothèque SDL .

0voto

Rohan Points 21

La haute résolution est relative... J'ai regardé les exemples et ils concernent principalement les millisecondes. Cependant, pour moi, il est important de mesurer les microsecondes. Je n'ai pas vu de solution indépendante de la plateforme pour les microsecondes et j'ai pensé que quelque chose comme le code ci-dessous serait utile. Je n'ai chronométré que sous Windows pour le moment et j'ajouterai très probablement une implémentation de gettimeofday() lorsque je ferai la même chose sous AIX/Linux.

    #ifdef WIN32
      #ifndef PERFTIME
        #include <windows.h>
        #include <winbase.h>
        #define PERFTIME_INIT unsigned __int64 freq;  QueryPerformanceFrequency((LARGE_INTEGER*)&freq); double timerFrequency = (1.0/freq);  unsigned __int64 startTime;  unsigned __int64 endTime;  double timeDifferenceInMilliseconds;
        #define PERFTIME_START QueryPerformanceCounter((LARGE_INTEGER *)&startTime);
        #define PERFTIME_END QueryPerformanceCounter((LARGE_INTEGER *)&endTime); timeDifferenceInMilliseconds = ((endTime-startTime) * timerFrequency);  printf("Timing %fms\n",timeDifferenceInMilliseconds);
    #define PERFTIME(funct) {unsigned __int64 freq;  QueryPerformanceFrequency((LARGE_INTEGER*)&freq);  double timerFrequency = (1.0/freq);  unsigned __int64 startTime;  QueryPerformanceCounter((LARGE_INTEGER *)&startTime);  unsigned __int64 endTime;  funct; QueryPerformanceCounter((LARGE_INTEGER *)&endTime);  double timeDifferenceInMilliseconds = ((endTime-startTime) * timerFrequency);  printf("Timing %fms\n",timeDifferenceInMilliseconds);}
      #endif
    #else
      //AIX/Linux gettimeofday() implementation here
    #endif

Utilisation :

PERFTIME(ProcessIntenseFunction());

or

PERFTIME_INIT
PERFTIME_START
ProcessIntenseFunction()
PERFTIME_END

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