Comment mesurer le temps en millisecondes à l'aide de la norme ANSI C?
En utilisant uniquement le C ANSI, est-il possible de mesurer le temps avec millisecondes de précision ou plus? J'ai été la navigation en temps.h mais je n'ai trouvé la deuxième précision fonctions.
- Notez la différence entre la précision et l'exactitude. Vous pouvez obtenir un temps avec précision à la milliseconde en prenant le temps en secondes et en multipliant par 1000, mais ce n'est pas utiliser. ms précision les fonctions ne sont pas nécessairement ms précision - bien qu'ils réussissent généralement mieux que 1s précision.
- La réponse simple est NON, ANSI C ne prend pas en charge la précision à la milliseconde ou mieux. Les plus complexes de la réponse dépend de ce que vous êtes en train de faire - franchement l'ensemble de la zone est un cauchemar, même si vous autorisez l'utilisation de la largement disponibles les fonctions Posix. Vous utilisez le terme "mesure" donc je suppose que vous êtes intéressé dans un intervalle plutôt que "horloge murale" du temps. Mais êtes-vous tenter de mesurer le temps absolu de la période ou de l'utilisation de l'uc de votre processus?
- Je voulais juste dire à SOF juste sauvé ma bacon, encore une fois 😉
Vous devez vous connecter pour publier un commentaire.
Il n'existe pas de norme ANSI C fonction qui permet de mieux que de 1 seconde de temps de résolution, mais la fonction POSIX
gettimeofday
fournit une résolution. La fonction d'horloge seulement des mesures de la quantité de temps qu'un processus a passé à l'exécution et n'est pas précis sur de nombreux systèmes.Vous pouvez utiliser cette fonction comme ceci:
Cela renvoie
Time elapsed: 1.000870
sur ma machine.timeval::tv_usec
est toujours sous une seconde, ça en boucle. I. e. afin de prendre des différences de temps de plus de 1 sec, vous devez:long usec_diff = (e.tv_sec - s.tv_sec)*1000000 + (e.tv_usec - s.tv_usec);
timespec_get
: stackoverflow.com/a/36095407/895245CLOCKS_PER_SEC / 1000
peuvent éventuellement être inexacte, ce qui pourrait affecter le résultat final (bien que dans mon expérienceCLOCKS_PER_SEC
a toujours été un multiple de 1000). Faire(1000 * clock()) / CLOCKS_PER_SEC
est moins sensible à la division de l'inexactitude, mais d'un autre côté il est plus sensible à un débordement. Juste quelques questions à prendre en considération.clock()
mesures mur-temps sur Windows et temps CPU sur la plupart des autres populaire des Systèmes d'exploitation.J'ai toujours utiliser la clock_gettime() fonction retournant de temps à partir de la CLOCK_MONOTONIC de l'horloge. L'heure du retour est la quantité de temps, en secondes et nanosecondes, depuis quelques indéterminée dans le passé, tels que le système de démarrage de l'époque.
clock_gettime(CLOCK_MONOTONIC, ...)
et il y a même les macros de test de fonctionnalité_POSIX_MONOTONIC_CLOCK
.Mise en œuvre d'une solution portable
Comme il a déjà été mentionné ici qu'il n'existe pas de norme ANSI solution avec suffisamment de précision pour la mesure du temps de problème, je veux écrire sur les manières de procéder pour obtenir un portable et, si possible, une haute résolution de la mesure du temps de solution.
Monotone de l'horloge en fonction du temps de timbres
En général il y a deux façons de la mesure du temps:
La première utilise une fonction monotone compteur d'horloge (il est parfois appelé un compteur de cycles) qui compte les tiques avec une fréquence prédéfinie, donc si vous avez un tiques de la valeur et de la fréquence est connue, vous pouvez facilement convertir les tiques de temps écoulé. Il n'est pas garanti qu'une fonction monotone de l'horloge reflète l'heure actuelle du système en aucune façon, il peut aussi compter les tiques depuis le démarrage du système. Mais elle garantit que l'horloge est toujours en place dans de plus en plus de la mode, indépendamment de l'état du système. Habituellement, la fréquence est liée à un matériel de haute résolution de la source, c'est pourquoi il fournit une haute précision (dépend du matériel, mais la plupart du matériel moderne n'a pas de problèmes avec la haute résolution des sources d'horloge).
Le deuxième offre un (date)le temps de la valeur basée sur l'horloge système en cours de la valeur. Il peut également avoir une haute résolution, mais il a un inconvénient majeur: ce genre de temps la valeur peut être affectée par différents système d'ajustements en temps, c'est à dire changement de fuseau horaire, heure d'été (DST) changement, NTP serveur de mise à jour, l'hibernation du système et ainsi de suite. Dans certains cas, vous pouvez obtenir un négatif, le temps écoulé de la valeur qui peut conduire à un comportement indéfini. En fait, ce type de source de temps est de moins en moins fiable que le premier.
Donc la première règle dans l'intervalle de temps de mesure est d'utiliser une fonction monotone de l'heure si possible. Il a généralement une grande précision, et il est fiable par la conception.
Stratégie de repli
Lors de la mise en œuvre d'une solution portable, il convient de considérer une stratégie de repli: l'utilisation d'une fonction monotone de l'horloge si disponible et de secours à l'heure timbres approche si il n'est pas une fonction monotone de l'horloge du système.
Windows
Il y a un grand article intitulé L'acquisition de temps à haute résolution des timbres sur MSDN sur la mesure du temps sur Windows qui décrit tous les détails que vous devez savoir sur les logiciels et le matériel de soutien. Pour acquérir une haute précision de l'horodatage sur Windows, vous devez:
requête d'une minuterie de fréquence (impulsions par seconde) avec QueryPerformanceFrequency:
La minuterie de la fréquence est fixe sur le système de démarrage de sorte que vous devez obtenir qu'une seule fois.
requête de l'actuel tiques valeur avec QueryPerformanceCounter:
échelle de la tiques de temps écoulé, c'est à dire à microsecondes:
Selon Microsoft, vous ne devriez pas avoir des problèmes avec cette approche sur Windows XP et versions ultérieures, dans la plupart des cas. Mais vous pouvez également utiliser les deux solutions de secours sur Windows:
GetTickCount
, mais il est disponible à partir de Windows Vista et au-dessus.OS X (mac os)
OS X (mac os) a son propre Mach temps absolu unités qui représentent une fonction monotone de l'horloge. La meilleure façon de commencer est la Pomme de l'article Technique Q&UN QA1398: Mach Absolu Unités de Temps qui décrit (avec les exemples de code) comment utiliser Mach-API spécifique pour obtenir monotone tiques. Il y a aussi un local de question à ce sujet appelé clock_gettime alternative dans Mac OS X qui à la fin peut vous laisser un peu confus quoi faire avec la valeur possible de débordement car le compteur de fréquence est utilisé sous la forme du numérateur et du dénominateur. Donc, un petit exemple de comment obtenir du temps écoulé:
obtenir la fréquence de l'horloge du numérateur et du dénominateur:
Vous avez besoin de le faire qu'une seule fois.
requête de l'actuelle valeur de graduation avec
mach_absolute_time
:échelle de la tiques de temps écoulé, c'est à dire à microsecondes, à l'aide de déjà interrogé le numérateur et le dénominateur:
L'idée principale pour éviter un dépassement de capacité est de réduire les tiques à la précision désirée avant d'utiliser le numérateur et le dénominateur. Comme la première résolution du timer est en nanosecondes, on la divise par
1000
pour obtenir microsecondes. Vous pouvez trouver la même approche utilisée dans le Chrome est time_mac.c. Si vous avez vraiment besoin d'une précision de l'ordre de la nanoseconde envisager la lecture de l' Comment puis-je utiliser mach_absolute_time sans déborder?.Linux et UNIX
La
clock_gettime
appel est votre meilleure manière sur n'importe quel POSIX-système favorable à l'. Elle peut moment de la requête à partir de différentes sources d'horloge, et celle que nous avons besoin estCLOCK_MONOTONIC
. Pas tous les systèmes qui ontclock_gettime
soutienCLOCK_MONOTONIC
, de sorte que la première chose que vous devez faire est de vérifier sa disponibilité:_POSIX_MONOTONIC_CLOCK
est définie à une valeur>= 0
cela signifie queCLOCK_MONOTONIC
est disponible;si
_POSIX_MONOTONIC_CLOCK
est défini à0
cela signifie que vous devez en outre vérifier si il fonctionne au moment de l'exécution, je suggère l'utilisation desysconf
:Utilisation de
clock_gettime
est assez simple:obtenir la valeur de temps:
J'ai réduit le temps de microsecondes ici.
calculer la différence avec la précédente valeur reçue de la même façon:
La meilleure stratégie de repli est d'utiliser le
gettimeofday
appel: il n'est pas monotone, mais il fournit une assez bonne résolution. L'idée est la même qu'avecclock_gettime
, mais pour obtenir une valeur de temps, vous devriez:De nouveau, la valeur de temps est réduite à quelques microsecondes.
SGI IRIX
IRIX a la
clock_gettime
appel, mais il manqueCLOCK_MONOTONIC
. Au lieu de cela, il a ses propres monotone de la source d'horloge définie commeCLOCK_SGI_CYCLE
que vous devez utiliser à la place deCLOCK_MONOTONIC
avecclock_gettime
.Solaris et HP-UX
Solaris a son propre timer haute résolution de l'interface
gethrtime
qui retourne la valeur actuelle du timer en nanosecondes. Bien que les nouvelles versions de Solaris peut avoirclock_gettime
, vous pouvez coller àgethrtime
si vous avez besoin de supporter les anciennes Solaris versions.Utilisation est simple:
HP-UX manque
clock_gettime
, mais il prend en chargegethrtime
que vous devriez utiliser de la même manière que sur Solaris.BeOS
BeOS dispose également de son propre timer haute résolution de l'interface
system_time
qui retourne le nombre de microsecondes se sont écoulés depuis que l'ordinateur a été démarré.Exemple d'utilisation:
OS/2
OS/2 a sa propre API pour récupérer de haute précision temps de timbres:
requête d'une minuterie de fréquence (impulsions par unité) avec
DosTmrQueryFreq
(pour le compilateur GCC):requête de l'actuel tiques valeur avec
DosTmrQueryTime
:échelle de la tiques de temps écoulé, c'est à dire à microsecondes:
Exemple de mise en œuvre
Vous pouvez prendre un coup d'oeil à la plibsys bibliothèque qui implémente toutes les décrit ci-dessus stratégies (voir ptimeprofiler*.c pour plus de détails).
timespec_get
: stackoverflow.com/a/36095407/895245timespec_get
n'est pas monotone.timespec_get
de C11Les retours jusqu'à la nanoseconde, arrondie à la résolution de la mise en œuvre.
Ressemble ANSI escroquerie de POSIX'
clock_gettime
.Exemple: un
printf
est effectuée toutes les 100ms sur Ubuntu 15.10:La C11 N1570 projet de norme 7.27.2.5 "La timespec_get fonction dit":
C++11 a également obtenu
std::chrono::high_resolution_clock
: C++ Multi-Plateforme Timer Haute Résolutionglibc 2.21 mise en œuvre
Peut être trouvé sous
sysdeps/posix/timespec_get.c
comme:clairement:
seulement
TIME_UTC
est actuellement pris en chargeil transmet à
__clock_gettime (CLOCK_REALTIME, ts)
, qui est une API POSIX: http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_getres.htmlLinux x86-64 est un
clock_gettime
appel système.Noter que ce n'est pas une preuve de l'échec de la micro-analyse comparative de la méthode, car:
man clock_gettime
dit que cette mesure peut avoir des discontinuités si la modification d'un système de réglage de l'heure alors que votre programme s'exécute. Cela devrait être un événement rare, bien sûr, et vous pourriez être en mesure de les ignorer.mesures de ce mur du temps, donc si l'ordonnanceur décide d'oublier votre tâche, il apparaîtra à courir plus longtemps.
Pour ces raisons
getrusage()
peut être un meilleur mieux POSIX outil d'analyse comparative, en dépit de la baisse de la microseconde un maximum de précision.Plus d'informations sur: La mesure du temps dans Linux - temps vs horloge vs getrusage vs clock_gettime vs gettimeofday vs timespec_get?
La meilleure précision, vous pouvez peut-être obtenir à travers l'utilisation de l'x86-seulement "rdtsc" de l'enseignement, qui peut fournir de l'horloge au niveau de la résolution (ne doit bien sûr prendre en compte le coût de la rdtsc appel lui-même, qui peut être mesurée facilement de démarrage de l'application).
La prise principale ici est de mesurer le nombre d'horloges par seconde, ce qui ne devrait pas être trop dur.
Accepté la réponse est assez bon.Mais ma solution est plus simple.Je viens de tester sous Linux, utilisez gcc (Ubuntu 7.2.0-8ubuntu3.2) 7.2.0.
Alse utilisation
gettimeofday
, letv_sec
est la partie de la deuxième, et latv_usec
est microsecondes, pas millisecondes.D'impression:
1522139691342
, exactement une seconde.1522139692342
Sous windows: