C++/POSIX comment obtenir une milliseconde horodatage de la manière la plus efficace?
Je suis en utilisant une bibliothèque libre pour bus i2c actions. Cette bibliothèque utilise fréquemment une fonction pour obtenir une réelle horodatage avec milliseconde.
Exemple D'Appel:
nowtime = timer_nowtime();
while ((i2c_CheckBit(dev) == true) && ((timer_nowtime() - nowtime) < I2C_TIMEOUT));
L'application à l'aide de cette i2c bibliothèque utilise beaucoup de la capacité du PROCESSEUR. J'ai compris, que le programme en cours d'exécution le plus de temps est l'appel de la fonction timer_nowtime()
.
La fonction d'origine:
unsigned long timer_nowtime(void) {
static bool usetimer = false;
static unsigned long long inittime;
struct tms cputime;
if (usetimer == false)
{
inittime = (unsigned long long)times(&cputime);
usetimer = true;
}
return (unsigned long)((times(&cputime) - inittime)*1000UL/sysconf(_SC_CLK_TCK));
}
Mon but aujourd'hui est, à améliorer l'efficacité de cette fonction. J'ai essayé de cette façon:
struct timespec systemtime;
clock_gettime(CLOCK_REALTIME, &systemtime);
//convert the to milliseconds timestamp
//incorrect way, because (1 /1000000UL) always returns 0 -> thanks Pace
//return (unsigned long) ( (systemtime.tv_sec * 1000UL) + (systemtime.tv_nsec
// * (1 /1000000UL)));
return (unsigned long) ((systemtime.tv_sec * 1000UL)
+ (systemtime.tv_nsec / 1000000UL));
Malheureusement, je ne peux pas déclarer cette fonction inline (aucune idée pourquoi).
Qui est plus efficace d'obtenir un timestamp réelle avec ms résolution?
Je suis sûr qu'il est plus per-formants façon de le faire. Toutes les suggestions?
grâce.
Rythme, vous êtes de droite. ( 1 / 1000000UL)= 0; je vais corriger mon code.
OriginalL'auteur Maus | 2010-01-04
Vous devez vous connecter pour publier un commentaire.
C'est clair que votre appel d'exemple utilise plus de temps CPU en
timer_nowtime()
fonction. Vous êtes d'interrogation, et la boucle mange votre temps CPU. Vous pourriez change la fonction de la minuterie avec une meilleure alternative et si vous pouvez obtenir plus d'itérations de boucle, mais on utilise toujours plus de temps CPU en fonction! Vous ne serez pas obtenir en utilisant moins de temps CPU par un changement dans la fonction de minuterie de!Vous pouvez changer votre boucle et d'introduire des temps d'attente, mais seulement si elle fait sens dans votre application, par exemple:
La minuterie: je pense que
gettimeofday()
serait une bonne décision, il a de haute précision et est disponible dans la plupart (tous?) Unices.gettimeofday()
n'est pas monotone, et il est soumis à NTP corrections, etc... Ce n'est pas la bonne solution ici. Vous souhaitez utiliserclock_gettime(CLOCK_MONOTONIC)
.OriginalL'auteur Frunsi
Noter que vos deux exemples ne sont pas équivalents; les temps(2) les mesures de temps CPU de la consommation, alors que clock_gettime(CLOCK_REALTIME, ...) des mesures de la wallclock temps.
Cela étant dit, wallclock minuteries comme clock_gettime plus âgés ou gettimeofday sont généralement beaucoup plus rapide que le CPU minuteries comme times() ou getrusage().
Et, comme l'a déjà noté, votre fonction de synchronisation est à l'aide de beaucoup de temps CPU parce que vous n'avez rien d'autre que d'interrogation. Si c'est un problème, attendre un peu, par exemple en appelant nanosleep() ou clock_nanosleep().
Je pense que votre meilleure option est d'utiliser clock_gettime(), mais avec CLOCK_MONOTONIC au lieu de CLOCK_REALTIME.
OriginalL'auteur janneb
Si votre programme s'exécute uniquement sur les récents processeurs Intel/AMD transformateurs, mais pas trop récent (l'horloge de la limitation n'est pas très bien traitée), le RDTSC instructions de montage est la meilleure façon d'obtenir un horodatage. La résolution est proche du réel de l'horloge du processeur et qu'il est indépendant du système (ce qui signifie qu'il est biaisé par les interruptions, trop. Vous ne pouvez pas avoir votre gâteau et le manger aussi).
Cette page a un exemple dans C.
RDTSC ne doit pas être utilisé pour le chronométrage (pas plus..): en.wikipedia.org/wiki/Time_Stamp_Counter!
Je dis "pas trop récente" 🙂
Depuis le timerfunction est utilisé pour déterminer combien de temps passa, et le logiciel est en cours d'exécution sur un PROCESSEUR intégré de l'appareil, cette solution serait une option. Bien sûr, cela ne serait pas conforme POSIX et difficile à port sur une autre plate-forme.
Si votre PROCESSEUR est assez récent (comme Core2 ou Nehalem), puis
rdtsc
est un timesource. Continu et invariant TSC dire qu'il a toujours les tiques à fréquence constante, peu importe si le core de l'horloge est arrêtée ou en cours d'exécution plus rapide ou plus lente que la tension nominale / autocollant de fréquence. Voir mauvais cycle d'horloge mesures avec rdtsc pour un peu d'histoire. Il y avait un âge sombre où RDTSC n'était pas utile en tant que timesource ou pour le cycle-précis de mesure de la performance, mais que le temps a passé. Maintenant, c'est seulement un timesource, et vous avez besoin de perf compteurs...OriginalL'auteur Pascal Cuoq
J'ai été heureux avec ce sur Linux:
OriginalL'auteur Dirk Eddelbuettel
Vous pouvez essayer le code suivant si vous exécuter sur le processeur Intel
RDTSC ne doit pas être utilisé pour le chronométrage (pas plus..): en.wikipedia.org/wiki/Time_Stamp_Counter!
OriginalL'auteur Douglas L