GNU/Linux >> Tutoriels Linux >  >> Linux

Mesurer le temps sous Linux - time vs clock vs getrusage vs clock_gettime vs gettimeofday vs timespec_get ?

Le problème est qu'il existe plusieurs fonctions temporelles différentes disponibles en C et C++, et certaines d'entre elles varient en comportement entre les implémentations. Il y a aussi beaucoup de demi-réponses qui circulent. Compiler une liste de fonctions d'horloge avec leurs propriétés répondrait correctement à la question. Pour commencer, demandons quelles sont les propriétés pertinentes que nous recherchons. En regardant votre message, je suggère :

  • Quelle heure est mesurée par l'horloge ? (réel, utilisateur, système ou, espérons-le pas, horloge murale ?)
  • Quelle est la précision de l'horloge ? (s, ms, µs ou plus rapide ?)
  • Après combien de temps l'horloge tourne-t-elle ? Ou existe-t-il un mécanisme pour éviter cela ?
  • L'horloge est-elle monotone ou changera-t-elle avec les changements d'heure système (via NTP, fuseau horaire, heure d'été, par l'utilisateur, etc.) ?
  • Comment les éléments ci-dessus varient-ils d'une mise en œuvre à l'autre ?
  • La fonction spécifique est-elle obsolète, non standard, etc. ?

Avant de commencer la liste, je tiens à souligner que l'heure de l'horloge murale est rarement la bonne heure à utiliser, alors qu'elle change avec les changements de fuseau horaire, les changements d'heure d'été ou si l'horloge murale est synchronisée par NTP. Aucune de ces choses n'est bonne si vous utilisez le temps pour planifier des événements ou pour comparer les performances. Ce n'est vraiment bon que pour ce que son nom l'indique, une horloge sur le mur (ou sur le bureau).

Voici ce que j'ai trouvé jusqu'à présent pour les horloges sous Linux et OS X :

  • time() renvoie l'heure de l'horloge murale à partir du système d'exploitation, avec une précision en secondes.
  • clock() semble renvoyer la somme du temps utilisateur et du temps système. Il est présent dans C89 et plus tard. À un moment donné, cela était censé être le temps CPU en cycles, mais les normes modernes comme POSIX exigent que CLOCKS_PER_SEC soit 1000000, donnant une précision maximale possible de 1 µs. La précision sur mon système est en effet de 1 µs. Cette horloge se termine une fois qu'elle atteint son maximum (cela se produit généralement après ~ 2 ^ 32 ticks, ce qui n'est pas très long pour une horloge de 1 MHz). man clock dit que depuis glibc 2.18, il est implémenté avec clock_gettime(CLOCK_PROCESS_CPUTIME_ID, ...) sous Linux.
  • clock_gettime(CLOCK_MONOTONIC, ...) fournit une résolution nanoseconde, est monotone. Je crois que les "secondes" et les "nanosecondes" sont stockées séparément, chacune dans des compteurs 32 bits. Ainsi, tout bouclage se produirait après plusieurs dizaines d'années de disponibilité. Cela ressemble à une très bonne horloge, mais malheureusement elle n'est pas encore disponible sur OS X. POSIX 7 décrit CLOCK_MONOTONIC en tant qu'extension facultative.
  • getrusage() s'est avéré être le meilleur choix pour ma situation. Il signale les heures de l'utilisateur et du système séparément et ne fait pas le tour. La précision sur mon système est de 1 µs, mais je l'ai également testé sur un système Linux (Red Hat 4.1.2-48 avec GCC 4.1.2) et là la précision n'était que de 1 ms.
  • gettimeofday() renvoie l'heure de l'horloge murale avec (nominalement) une précision en µs. Sur mon système, cette horloge semble avoir une précision en µs, mais ce n'est pas garanti, car "la résolution de l'horloge système dépend du matériel". POSIX.1-2008 le dit. "Les applications doivent utiliser le clock_gettime() fonction au lieu de l'obsolescent gettimeofday() fonction ", vous devez donc rester à l'écart. Linux x86 et l'implémente en tant qu'appel système.
  • mach_absolute_time() est une option pour la synchronisation à très haute résolution (ns) sur OS X. Sur mon système, cela donne en effet une résolution ns. En principe, cette horloge s'enroule, mais elle stocke ns en utilisant un entier non signé 64 bits, de sorte que l'enroulement ne devrait pas être un problème en pratique. La portabilité est discutable.
  • J'ai écrit une fonction hybride basée sur cet extrait qui utilise clock_gettime lorsqu'elle est compilée sur Linux, ou une minuterie Mach lorsqu'elle est compilée sur OS X, afin d'obtenir une précision ns sur Linux et OS X.

Tous les éléments ci-dessus existent à la fois sous Linux et OS X, sauf indication contraire. "Mon système" ci-dessus est un Apple exécutant OS X 10.8.3 avec GCC 4.7.2 de MacPorts.

Enfin, voici une liste de références que j'ai trouvées utiles en plus des liens ci-dessus :

  • http://blog.habets.pp.se/2010/09/gettimeofday-should-never-be-used-to-measure-time
  • Comment mesurer le temps d'exécution RÉEL d'un programme C sous Linux ?
  • http://digitalsandwich.com/archives/27-benchmarking-misconceptions-microtime-vs-getrusage.html
  • http://www.unix.com/hp-ux/38937-getrusage.html

Mettre à jour :pour OS X, clock_gettime a été implémenté à partir de 10.12 (Sierra). De plus, les plates-formes basées sur POSIX et BSD (comme OS X) partagent le rusage.ru_utime champ de structure.


C11 timespec_get

Exemple d'utilisation sur :https://stackoverflow.com/a/36095407/895245

La précision maximale possible renvoyée est de nanosecondes, mais la précision réelle est définie par l'implémentation et peut être inférieure.

Il renvoie l'heure du mur, pas l'utilisation du processeur.

glibc 2.21 l'implémente sous sysdeps/posix/timespec_get.c et il transmet directement à :

clock_gettime (CLOCK_REALTIME, ts) < 0)

clock_gettime et CLOCK_REALTIME sont POSIX http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_getres.html et man clock_gettime indique que cette mesure peut présenter des discontinuités si vous modifiez certains paramètres d'heure système pendant l'exécution de votre programme.

Chrono C++11

Puisque nous y sommes, couvrons-les également :http://en.cppreference.com/w/cpp/chrono

GCC 5.3.0 (C++ stdlib est dans la source GCC) :

  • high_resolution_clock est un alias pour system_clock
  • system_clock transmet au premier des éléments suivants disponibles :
    • clock_gettime(CLOCK_REALTIME, ...)
    • gettimeofday
    • time
  • steady_clock transmet au premier des éléments suivants disponibles :
    • clock_gettime(CLOCK_MONOTONIC, ...)
    • system_clock

Question posée à :Différence entre std::system_clock et std::steady_clock ?

CLOCK_REALTIME contre CLOCK_MONOTONIC :Différence entre CLOCK_REALTIME et CLOCK_MONOTONIC ?


Linux
  1. Démarrer Linux plus rapidement

  2. Linux – Comment mesurer le temps d'arrivée d'un paquet ?

  3. timedatectl Exemples de commandes sous Linux

  4. Mesurer le temps écoulé sous Linux pour un programme c

  5. Comment Linux utilise-t-il une horloge en temps réel ?

Commande de temps Linux

Dernière commande sous Linux

Vérifier le fuseau horaire sous Linux

Linux date Exemples de commandes

Comprendre la commande time sous Linux

Ping Linux :Afficher le délai d'attente