web-dev-qa-db-fra.com

Mesurer le temps d'exécution d'un code C++?

Je veux mesurer le temps d'exécution de mon code C++. L'exécution de mon code prend environ 12 heures et je veux écrire cette heure à la fin de l'exécution de mon code. Comment puis-je le faire dans mon code?

Système d'exploitation: Linux

23
peaceman

Si vous utilisez C++ 11, vous pouvez utiliser system_clock::now():

auto start = std::chrono::system_clock::now();

/* do some work */

auto end = std::chrono::system_clock::now();
auto elapsed = end - start;
std::cout << elapsed.count() << '\n';

Vous pouvez également spécifier la granularité à utiliser pour représenter une durée:

// this constructs a duration object using milliseconds
auto elapsed =
    std::chrono::duration_cast<std::chrono::milliseconds>(end - start);

// this constructs a duration object using seconds
auto elapsed =
    std::chrono::duration_cast<std::chrono::seconds>(end - start);

Si vous ne pouvez pas utiliser C++ 11, jetez un coup d'œil à chrono de Boost.

La meilleure chose à propos de l’utilisation de telles bibliothèques standard est que leur portabilité est très élevée (par exemple, elles fonctionnent toutes les deux sous Linux et Windows). Vous n'avez donc pas à vous inquiéter trop si vous décidez de porter votre application par la suite.

Ces bibliothèques suivent également une conception C++ moderne, par opposition aux approches similaires à celles du C.

EDIT: L'exemple ci-dessus peut être utilisé pour mesurer heure de l'horloge murale . Ce n'est cependant pas le seul moyen de mesurer le temps d'exécution d'un programme. Tout d’abord, nous pouvons distinguer l’heure de l’utilisateur et celle du système:

  • Temps utilisateur: Temps passé par le programme en cours d'exécution dans espace utilisateur .
  • Temps système: Temps passé par le programme exécuté dans l'espace système (ou noyau). Un programme entre par exemple dans l’espace noyau lorsqu’il exécute un appel système .

En fonction des objectifs, il peut être nécessaire ou non de prendre en compte le temps système dans le temps d'exécution d'un programme. Par exemple, si l'objectif est simplement de mesurer l'optimisation d'un compilateur sur le code utilisateur, il est probablement préférable de laisser de côté le temps système. D'autre part, si l'utilisateur veut déterminer si les appels système représentent un temps système important, il est également nécessaire de mesurer le temps système.

De plus, comme la plupart des systèmes modernes sont à temps partagé , différents programmes peuvent être en concurrence pour plusieurs ressources de calcul (par exemple, un processeur). Dans un tel cas, une autre distinction peut être faite:

  • _ { Heure de l'horloge murale } _: En utilisant l'heure de l'horloge murale, l'exécution du programme est mesurée de la même manière que si nous utilisions une horloge externe (murale). Cette approche ne prend pas en compte l’interaction entre les programmes.
  • Temps CPU : Dans ce cas, nous ne comptons que la durée d'exécution réelle d'un programme sur la CPU. Si un programme (P1) est co-programmé avec un autre (P2) et que nous voulons obtenir le temps CPU pour P1, cette approche n'inclut pas le temps pendant lequel P2 est en cours d'exécution et P1 attend la CPU (par opposition à l’approche de l’horloge murale).

Pour mesurer le temps de calcul, Boost comprend un ensemble d'horloges supplémentaires :

  • process_real_cpu_clock, capture le temps CPU de l'horloge murale passé par le processus en cours.
  • process_user_cpu_clock, capture le temps CPU utilisateur passé par le processus en cours.
  • process_system_cpu_clock, capture le temps CPU-système passé par le processus en cours. Une classe Tuple-like process_cpu_clock, qui capture ensemble les temps de traitement réels, CPU utilisateur et système.
  • Une horloge constante thread_clock de threads donnant le temps passé par le thread actuel (si pris en charge par une plate-forme).

Malheureusement, C++ 11 n'a pas de telles horloges. Mais Boost est une bibliothèque largement utilisée et, probablement, ces horloges supplémentaires seront incorporées à C++ 1x à un moment donné. Donc, si vous utilisez Boost, vous serez prêt lorsque la nouvelle norme C++ les ajoutera.

Enfin, si vous souhaitez mesurer le temps d'exécution d'un programme à partir de la ligne de commande (par opposition à l'ajout de code dans votre programme), vous pouvez jeter un coup d'œil à la commande time , exactement comme @ BЈовић. suggère. Cependant, cette approche ne vous permettrait pas de mesurer des parties individuelles de votre programme (par exemple, le temps nécessaire pour exécuter une fonction).

69
betabandido

Utilisez std::chrono::steady_clock et non std::chrono::system_clock pour mesurer le temps d'exécution en C++ 11. La raison en est (citant la documentation de system_clock):

sur la plupart des systèmes, l'heure système peut être ajustée à tout moment

tandis que steady_clock est monotone et convient mieux pour mesurer des intervalles:

La classe std :: chrono :: steady_clock représente une horloge monotone. Le temps les points de cette horloge ne peuvent pas diminuer à mesure que le temps physique avance . Cette horloge n’est pas liée à l’heure de l’horloge murale et convient mieux à intervalles de mesure.

Voici un exemple:

auto start = std::chrono::steady_clock::now();
// do something
auto finish = std::chrono::steady_clock::now();
double elapsed_seconds = std::chrono::duration_cast<
  std::chrono::duration<double> >(finish - start).count();

Un petit conseil pratique: si vous mesurez le temps d'exécution et souhaitez signaler les secondes, std::chrono::duration_cast<std::chrono::seconds> est rarement ce dont vous avez besoin, car il vous donne entier nombre de secondes. Pour obtenir le temps en secondes sous la forme d'une double, utilisez l'exemple ci-dessus.

22
vitaut

Vous pouvez utiliser time pour démarrer votre programme. Une fois terminé, il affiche les statistiques temporelles de Nice sur l'exécution du programme. Il est facile de configurer quoi imprimer. Par défaut, il imprime les temps utilisateur et CPU nécessaires à l’exécution du programme.

EDIT: Notez que chaque mesure du code n’est pas correcte, car votre application sera bloquée par d’autres programmes, vous donnant ainsi des valeurs erronées.*.

* Par de mauvaises valeurs, je voulais dire qu'il est facile de connaître le temps nécessaire à l'exécution du programme, mais que ce temps varie en fonction de la charge du processeur pendant l'exécution du programme. Pour obtenir une mesure du temps relativement stable, qui ne dépend pas de la charge du processeur, vous pouvez exécuter l'application à l'aide de time et utiliser le processeur comme résultat de la mesure.

10
BЈовић

J'ai utilisé quelque chose comme ça dans l'un de mes projets:

#include <sys/time.h>

struct timeval start, end;
gettimeofday(&start, NULL);
//Compute
gettimeofday(&end, NULL);
double elapsed = ((end.tv_sec - start.tv_sec) * 1000) 
        + (end.tv_usec / 1000 - start.tv_usec / 1000);

C'est pour millisecondes et cela fonctionne à la fois pour C et C++.

9
Kjir

Vous pouvez également essayer des classes de minuterie qui démarrent et s’arrêtent automatiquement et rassembler des statistiques sur le temps moyen, maximum et minimum passé dans un bloc de code, ainsi que sur le nombre d’appels. Ces classes cxx-rtimer sont disponibles sur GitHub , et prennent en charge l’utilisation de std :: chrono, clock_gettime () ou de boost :: posix_time comme source d’horloge dorsale.

Avec ces minuteries, vous pouvez faire quelque chose comme:

void timeCriticalFunction() {
    static rtimers::cxx11::DefaultTimer timer("expensive");
    auto scopedStartStop = timer.scopedStart();
    // Do something costly...
}

avec les statistiques de synchronisation écrites sur std :: cerr à la fin du programme.

0
rwp