Mesure du temps
Unix times
time
est un outil Linux très simple permettant d’indiquer le temps d’exécution
d’une application.
Exemple :
time ./clock 1000000 > /dev/null
real 0m 1.03s // temps total
user 0m 1.02s // temps CPU utilisé en mode user
sys 0m 0.00s // temps CPU utilisé en mode system
Cet outil est basé sur la méthode times()
fournit par la bibliothèque
times.h
.
Sa simplicité pâtit d’une résolution souvent insuffisante. Le temps retourné est donné en nombre de cycles d’horloge système, laquelle peut varier fortement selon les performances du microprocesseur mis en œuvre.
Horloges (timers)
Linux dispose d’horloges à haute résolution. Celles-ci sont disponibles par la
bibliothèque time.h
Opération | syscall |
---|---|
Lire l’horloge | clock_gettime |
Lire la résolution | clock_getres |
Le développeur peut modifier l’application pour y ajouter des lectures de ces horloges et ainsi mesurer le temps d’exécution de parties ciblées de code.
Avantages :
- Simple à mettre en œuvre
- Grand nombre de points de mesure possible
Inconvénients :
- Il faut connaître les parties du code à mesurer
- Impacte le comportement de l’application
Horloges - Exemple
#define _GNU_SOURCE
#include <stdio.h>
#include <time.h>
static void do_something() {}
int main() {
struct timespec t1;
struct timespec t2;
clock_gettime(CLOCK_MONOTONIC, &t1);
do_something();
clock_gettime(CLOCK_MONOTONIC, &t2);
// compute elapsed time in nano-seconds
long long int delta_t = (long long)(t2.tv_sec - t1.tv_sec) * 1000000000 +
t2.tv_nsec - t1.tv_nsec;
printf("elapsed time: %lld [ns]\n", delta_t);
return 0;
}
Horloges - Interface
Sous Linux, la bibliothèque <time.h>
propose 3 horloges distinctes
CLOCK_REALTIME
: Temps actuel synchronisé avec NTPCLOCK_MONOTONIC
: Temps monotone, temps absolu depuis un point de départ non fixéCLOCK_PROCESS_CPUTIME_ID
: Temps utilisé par le processus
Le temps est donné en nanoseconds à l’aide de la structure suivante :
struct timespec {
time_t tv_sec; // seconds
long tv_nsec; // nanoseconds
};
Horloges - Coût de la mesure
Il est important de noter que la mesure du temps a également un coût (overhead). Pour obtenir ce coût, il suffit de réaliser la mesure suivante :
struct timespec t1, t2;
clock_gettime(CLOCK_MONOTONIC, &t1);
clock_gettime(CLOCK_MONOTONIC, &t2);
long long overhead =
(long long)(t2.tv_sec - t1.tv_sec) * 1000000000 + t2.tv_nsec - t1.tv_nsec;
Si l’on effectue cette mesure plusieurs fois on obtient les points suivants :
Sur la base des mesures précédentes, on peut obtenir la résolution de l’horloge :
Dans le cas du NanoPi Neo Plus2: horloge à \(24\, \mathsf{MHz} \rightarrow \frac{1}{24\cdot 10^{6}}\, \mathsf{s} = 41.\overline{6}\, \mathsf{ns}\).
Oscilloscope
L’utilisation de sorties numériques et d’un oscilloscope peut s’avérer très utile si l’on souhaite une mesure très précise du temps
Avantages :
- Peu d’impact sur le comportement du logiciel
- Grande précision
- Mesure de la gigue possible
Inconvénients :
- Mise en œuvre complexe
- Peu de points de mesure possible
L’utilisation de sorties numériques nécessite un accès aux ports d’entrées/sorties du microprocesseur
2 chemins disponibles :
- Utilisation des GPIO disponibles dans le sysfs (
/sys/class/gpio/...
) : Simple à mettre en œuvre, mais peut être trop lent (nécessite un accès aux routines du noyau) - Accès direct aux modules GPIO en mappant les contrôleurs en espace utilisateur
(méthode
mmap
) : Peu d’impacte sur le comportement du logiciel (que quelques cycles d’horloge), mais nécessite une très bonne compréhension du hardware