Parmi les fonctions de minutage, time
, clock
getrusage
, clock_gettime
, gettimeofday
et timespec_get
, Je veux comprendre clairement comment elles sont mises en œuvre et quelles sont leurs valeurs de retour afin de savoir dans quelle situation je dois les utiliser.
Nous devons d’abord classer les fonctions retournant valeurs de wall-clock par rapport aux fonctions retournant valeurs de processus ou de threads. gettimeofday
renvoie la valeur de l'horloge murale, clock_gettime
renvoie la valeur de l'horloge murale o les valeurs de processus ou de threads en fonction du paramètre Clock
qui lui a été transmis. getrusage
et clock
renvoient des valeurs de processus.
Ensuite, la deuxième question concerne la mise en œuvre de ces fonctions et, par conséquent, leur précision. Quel mécanisme matériel ou logiciel ces fonctions utilisent-elles.
Il semble que getrusage
utilise uniquement le tick du noyau (généralement 1 ms) et ne peut donc pas être plus précis que le ms. Est ce bien? Ensuite, la fonction getimeofday
semble utiliser le matériel sous-jacent le plus précis disponible. En conséquence, sa précision est généralement de l'ordre de la microseconde (ne peut pas être plus en raison de l'API) sur du matériel récent. Qu'en est-il de clock
, la page de manuel parle d’approximation, que signifie-t-elle? Qu'en est-il de clock_gettime
, l’API est en nanosecondes. Cela signifie-t-il qu’elle peut être aussi précise si le matériel sous-jacent le permet? Qu'en est-il de la monotonie?
Y a-t-il d'autres fonctions?
Le problème est qu’il existe plusieurs fonctions de temps disponibles en C et C++, et que certaines d’entre elles présentent des comportements différents selon les implémentations. Il y a aussi beaucoup de demi-réponses qui circulent. La compilation d'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 post, je suggère:
Avant de commencer la liste, je voudrais souligner que l’horloge murale est rarement le bon moment, alors qu’elle change en fonction des changements de fuseau horaire, de l’heure avancée ou si l’horloge murale est synchronisée par NTP. Aucune de ces choses sont bonnes si vous utilisez le temps nécessaire pour planifier des événements ou pour évaluer les performances. Ce n'est que vraiment bon pour ce que le nom dit, une horloge sur le mur (ou 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 de l'heure utilisateur et de l'heure système. Il est présent dans C89 et plus tard. À un moment donné, ce temps était censé représenter le temps de calcul par cycle, mais les normes modernes comme POSIX exigent que CLOCKS_PER_SEC soit égal à 1000000, ce qui donne une précision maximale possible de 1 µs. La précision sur mon système est en effet de 1 µs. Cette horloge tourne autour une fois qu’elle dépasse (cela se produit généralement après environ 2 ^ 32 ticks, ce qui n’est pas très long pour une horloge de 1 MHz). man clock
Indique que depuis la glibc 2.18, il est implémenté avec clock_gettime(CLOCK_PROCESS_CPUTIME_ID, ...)
sous Linux.clock_gettime(CLOCK_MONOTONIC, ...)
fournit une résolution en nanosecondes, 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, il n’est pas encore disponible sur OS X. POSIX 7 décrit CLOCK_MONOTONIC
Comme une 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ée sur un système Linux (Red Hat 4.1.2-48 avec GCC 4.1.2) et la précision n’était que de 1 ms.gettimeofday()
renvoie l'heure de l'horloge murale avec une précision (nominale) µs. Sur mon système, cette horloge semble avoir une précision de µs, mais cela n’est pas garanti, car "la résolution de l’horloge système dépend du matériel" . POSIX.1-2008 dit que . "Les applications doivent utiliser la fonction clock_gettime()
au lieu de la fonction obsolète gettimeofday()
", vous devez donc vous en tenir éloigné. Linux x86 et l'implémente en tant qu'appel système .mach_absolute_time()
est une option permettant une synchronisation très haute résolution (ns) sous OS X. Sur mon système, cela donne bien une résolution de ns. En principe, cette horloge est enveloppante, mais elle stocke ns en utilisant un entier non signé de 64 bits, de sorte que l'encapsulation ne devrait pas être un problème en pratique. La portabilité est discutable.Tout ce qui précède existe sous Linux et OS X, sauf indication contraire. "Mon système" dans ce qui précède est un Apple sous 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:
Mise à jour : pour OS X, clock_gettime
A été implémenté à partir de 10.12 (Sierra). De plus, les plates-formes POSIX et BSD (comme OS X) partagent le champ struct rusage.ru_utime
.
C11 timespec_get
Exemple d'utilisation à l'adresse suivante: 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 la mise en œuvre et peut être inférieure.
Il retourne l'heure du mur, pas l'utilisation du processeur.
la glibc 2.21 l'implémente sous sysdeps/posix/timespec_get.c
et est transmise 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 avoir des discontinuités si vous modifiez un réglage de l'heure du système pendant l'exécution de votre programme.
C++ 11 chrono
Puisque nous y sommes, couvrons-les également: http://en.cppreference.com/w/cpp/chrono
GCC 5.3.0 (C++ stdlib est à l'intérieur de la source GCC):
high_resolution_clock
est un alias pour system_clock
system_clock
transmet au premier des éléments suivants qui sont disponibles: clock_gettime(CLOCK_REALTIME, ...)
gettimeofday
time
steady_clock
transmet au premier des éléments suivants qui sont disponibles: clock_gettime(CLOCK_MONOTONIC, ...)
system_clock
Question posée à: Différence entre std :: system_clock et std :: steady_clock?
CLOCK_REALTIME
Vs CLOCK_MONOTONIC
: Différence entre CLOCK_REALTIME et CLOCK_MONOTONIC?