web-dev-qa-db-fra.com

mesure précise du temps

J'utilise time.h en C++ pour mesurer le timing d'une fonction.

clock_t t = clock();
someFunction();
printf("\nTime taken: %.4fs\n", (float)(clock() - t)/CLOCKS_PER_SEC);

cependant, je reçois toujours le temps pris en tant que 0,0000. clock () et t, lorsqu'ils sont imprimés séparément, ont la même valeur. Je voudrais savoir s'il existe un moyen de mesurer le temps avec précision (peut-être dans l'ordre des nanosecondes) en C++. J'utilise VS2010.

44
Abhishek Thakur

J'utilise habituellement la fonction QueryPerformanceCounter .

exemple:

LARGE_INTEGER frequency;        // ticks per second
LARGE_INTEGER t1, t2;           // ticks
double elapsedTime;

// get ticks per second
QueryPerformanceFrequency(&frequency);

// start timer
QueryPerformanceCounter(&t1);

// do something
...

// stop timer
QueryPerformanceCounter(&t2);

// compute and print the elapsed time in millisec
elapsedTime = (t2.QuadPart - t1.QuadPart) * 1000.0 / frequency.QuadPart;
56
Constantinius

C++ 11 a introduit le API chrono , que vous pouvez utiliser pour obtenir des nanosecondes:

auto begin = std::chrono::high_resolution_clock::now();

// code to benchmark

auto end = std::chrono::high_resolution_clock::now();
std::cout << std::chrono::duration_cast<std::chrono::nanoseconds>(end-begin).count() << "ns" << std::endl;

Pour une valeur plus pertinente, il est bon d'exécuter la fonction plusieurs fois et de calculer la moyenne:

auto begin = std::chrono::high_resolution_clock::now();
uint32_t iterations = 10000;
for(uint32_t i = 0; i < iterations; ++i)
{
    // code to benchmark
}
auto end = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(end-begin).count();
std::cout << duration << "ns total, average : " << duration / iterations << "ns." << std::endl;

Mais rappelez-vous la boucle for et attribuer begin et end var utilisent également un peu de temps CPU.

91
Axel Guilmin

Le texte suivant, avec lequel je suis tout à fait d’accord, est cité de logiciel d’optimisation en C++ (bonne lecture pour tout programmeur C++) -

Les mesures de temps peuvent nécessiter une résolution très élevée si les intervalles de temps sont courts. Sous Windows, vous pouvez utiliser les fonctions GetTickCount ou QueryPerformanceCounter pour une résolution en millisecondes. Une résolution beaucoup plus élevée peut être obtenue avec le compteur d'horodatage de la CPU, qui compte à la fréquence d'horloge de la CPU.

Le problème est que "la fréquence d'horloge peut varier de manière dynamique et que les mesures sont instables en raison d'interruptions et de changements de tâches".

6
SChepurin

En C ou C++, je fais habituellement comme ci-dessous. Si cela échoue toujours, vous pouvez envisager d’utiliser les fonctions rtdsc

      struct timeval time;
      gettimeofday(&time, NULL); // Start Time

      long totalTime = (time.tv_sec * 1000) + (time.tv_usec / 1000);

          //........ call your functions here

        gettimeofday(&time, NULL);  //END-TIME

        totalTime = (((time.tv_sec * 1000) + (time.tv_usec / 1000)) - totalTime);
2
hmatar