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é avecclock_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écritCLOCK_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 leclock_gettime()
fonction au lieu de l'obsolescentgettimeofday()
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 poursystem_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 ?