J’ai abordé dans plusieurs articles (Xenomai sur Pandaboard, GPIO, Pandaboard et temps réel – Gestion des interruptions, La Pandaboard au poteau de torture – Timers Xenomai…) la question des latences maximales de Xenomai. Mais il est aussi intéressant de connaître et de configurer correctement la latence minimale.
Mesure des latences
La notion de latence fait référence ici à la durée qui s’écoule entre le déclenchement d’une interruption et le début du traitement que nous avons associé à cette interruption. Cette durée dépend en grande partie du système d’exploitation et du matériel. On s’intéresse généralement à la latence maximale car c’est elle qui concerne les applications temps réel par exemple. Ainsi le cahier des charges d’un projet peut imposer qu’entre l’activation d’un capteur externe et la réponse du système il ne s’écoule pas plus de 100 microsecondes quels que soient la charge logicielle ou la quantité d’interruptions se déclenchant à ce moment.
La latence maximale se mesure avec des expériences de longues durées (plusieurs jours voire plusieurs semaines) sous une très haute charge (en tâches et en interruptions). À titre d’exemple, nous avons observé dans les articles mentionnés plus haut que sur une carte Pandaboard, le système Xenomai 2.6.1 nous permet d’obtenir une latence maximale de 50 microsecondes environ.
Pour cela, un utilitaire livré avec Xenomai mesure le temps s’écoulant entre le déclenchement d’un timer matériel et l’activation de la routine de traitement. Cet outil s’appelle latency
, voici un exemple d’utilisation sur un système faiblement chargé.
# /usr/xenomai/bin/latency -p 100 -T 14400 == Sampling period: 100 us == Test mode: periodic user-mode task == All results in microseconds warming up... RTT| 00:00:01 (periodic user-mode task, 100 us period, priority 99) RTH|----lat min|----lat avg|----lat max|-overrun|---msw|---lat best|--lat worst RTD| 0.724| 0.996| 13.918| 0| 0| 0.724| 13.918 RTD| 0.490| 1.182| 12.357| 0| 0| 0.490| 13.918 RTD| 0.486| 0.966| 8.396| 0| 0| 0.486| 13.918 RTD| 0.468| 1.001| 14.261| 0| 0| 0.468| 14.261 RTD| 0.478| 0.970| 12.934| 0| 0| 0.468| 14.261 RTD| 0.476| 0.988| 6.640| 0| 0| 0.468| 14.261 RTD| 0.494| 1.001| 8.414| 0| 0| 0.468| 14.261 RTD| 0.488| 0.964| 9.918| 0| 0| 0.468| 14.261 RTD| 0.476| 0.956| 7.882| 0| 0| 0.468| 14.261 RTD| 0.484| 0.956| 8.386| 0| 0| 0.468| 14.261 RTD| 0.486| 0.960| 7.815| 0| 0| 0.468| 14.261 RTD| 0.486| 0.972| 8.244| 0| 0| 0.468| 14.261 [...]
Les options utilisées ici indiquent que le timer doit suivre une période de 100 microsecondes, et que la durée totale de la mesure sera de 14400 secondes soient 4 heures.
L’outil latency
affiche une ligne de résultats intermédiaires toutes les secondes, sur lesquelles il présente les latences minimales (lat min
), moyennes (lat avg
) et maximales (lat max
) rencontrées pendant la seconde écoulée. Ensuite il indique les dépassements de timers (overrun
) et les changements de mode (msw
) au sens de Xenomai.
Enfin les deux dernières colonnes indiquent les plus courtes (lat best
) et plus longues (lat worst
) latences rencontrées sur tout le déroulement du processus.
Au bout de quatre heures l’expérience se termine sur les résultats suivants.
RTD| 0.482| 0.976| 8.652| 0| 0| -0.393| 31.192 RTD| 0.496| 0.968| 6.450| 0| 0| -0.393| 31.192 RTD| 0.527| 0.982| 13.291| 0| 0| -0.393| 31.192 RTD| 0.494| 0.964| 7.890| 0| 0| -0.393| 31.192 RTD| 0.456| 0.960| 6.482| 0| 0| -0.393| 31.192 RTD| 0.492| 0.970| 12.140| 0| 0| -0.393| 31.192 RTD| 0.498| 0.966| 7.265| 0| 0| -0.393| 31.192 RTD| 0.503| 0.980| 9.224| 0| 0| -0.393| 31.192 ---|-----------|-----------|-----------|--------|------|------------------------- RTS| -0.393| 0.900| 31.192| 0| 0| 04:00:00/04:00:00 #
Nous voyons que la pire latence rencontrée ici est de 31.192 microsecondes. Mais le système n’était pas très sollicité et on pourrait rencontrer des latences jusqu’à 50 microsecondes environ sous une forte charge.
Ce qui est plus surprenant c’est la latence minimale : elle est négative ! Cela signifierait donc que la routine de traitement se déclenche avant l’interruption timer ? Plutôt étrange…
Anticipation de la latence minimale
En réalité, lorsque Xenomai programme le déclenchement d’un timer, il anticipe la durée qui s’écoulera entre l’interruption matérielle et l’arrivée dans la routine de traitement. Ainsi nous obtenons de meilleures performances pour l’ensemble des tâches différées ou périodiques.
Mais comment peut-il anticiper la durée ? Simplement en se basant sur une valeur préprogrammée, que l’on peut consulter dans le pseudo-fichier /proc/xenomai/latency
. En voici un exemple.
[Panda]# cat /proc/xenomai/latency 2499 [Panda]#
Xenomai considère qu’il s’écoulera environ 2.5 microsecondes au minimum entre l’arrivée d’une interruption et son traitement, aussi avance-t-il de cette durée les timers qu’il programme.
Mais cette valeur est préprogrammée arbitrairement. Il serait intéressant de l’ajuster expérimentalement en fonction de notre matériel. Pour cela il faut simplement effacer la latence minimale, et relancer le programme latency
.
# echo 0 > /proc/xenomai/latency # /usr/xenomai/bin/latency -p 100 -T 14400 == Sampling period: 100 us == Test mode: periodic user-mode task == All results in microseconds warming up... RTT| 00:00:01 (periodic user-mode task, 100 us period, priority 99) RTH|----lat min|----lat avg|----lat max|-overrun|---msw|---lat best|--lat worst RTD| 3.204| 3.355| 9.928| 0| 0| 3.204| 9.928 RTD| 2.950| 3.234| 9.692| 0| 0| 2.950| 9.928 RTD| 2.962| 3.317| 11.464| 0| 0| 2.950| 11.464 RTD| 2.948| 3.134| 15.281| 0| 0| 2.948| 15.281 RTD| 2.930| 3.140| 9.974| 0| 0| 2.930| 15.281 [...] RTD| 2.966| 3.275| 10.553| 0| 0| 2.136| 18.827 RTD| 2.962| 3.283| 10.033| 0| 0| 2.136| 18.827 RTD| 2.962| 3.277| 9.607| 0| 0| 2.136| 18.827 RTD| 2.952| 3.277| 10.422| 0| 0| 2.136| 18.827 ---|-----------|-----------|-----------|--------|------|------------------------- RTS| 2.136| 3.216| 18.827| 0| 0| 04:00:00/04:00:00
Il n’y a plus d’anticipation, les latences sont donc naturellement un peu plus longues. Au bout de quatre heures, avec un système très peu chargé, nous avons obtenue une latence la plus faible de 2.136 microsecondes. Ce qui est plus faible que les 2.5 qui étaient préprogrammés auparavant et explique donc l’écart négatif de 0.39 microsecondes observé durant la première expérience.
Connaissant cette valeur minimale, nous pouvons l’inscrire dans /proc/xenomai/latency
et relancer l’expérience.
# echo 2136 > /proc/xenomai/latency # /usr/xenomai/bin/latency -p 100 -T 14400 == Sampling period: 100 us == Test mode: periodic user-mode task == All results in microseconds warming up... RTT| 00:00:01 (periodic user-mode task, 100 us period, priority 99) RTH|----lat min|----lat avg|----lat max|-overrun|---msw|---lat best|--lat worst RTD| 1.103| 1.265| 8.152| 0| 0| 1.103| 8.152 RTD| 0.853| 1.204| 8.138| 0| 0| 0.853| 8.152 RTD| 0.857| 1.216| 7.853| 0| 0| 0.853| 8.152 [...] RTD| 0.827| 1.047| 8.321| 0| 0| 0.039| 21.178 RTD| 0.839| 1.043| 7.926| 0| 0| 0.039| 21.178 RTD| 0.831| 1.041| 7.188| 0| 0| 0.039| 21.178 RTD| 0.829| 1.039| 7.587| 0| 0| 0.039| 21.178 ---|-----------|-----------|-----------|--------|------|------------------------- RTS| 0.039| 1.130| 21.178| 0| 0| 04:00:00/04:00:00
Cette fois notre système est très bien calibré, la latence minimale étant descendue à 39 nanosecondes.
Notez que la valeur exacte peut être ainsi inscrite dans /proc/xenomai/latency
dans le cours d’un script de démarrage par exemple, mais également être programmée « en dur » à la compilation du noyau dans le menu Real Time Sub-system, sous-menu Timing, option Scheduling latency (ns).
Conclusion
La configuration complète d’un système temps réel est un processus long, qui nécessite des expérimentations sur de longues durées avec des charges très variées tant en processus qu’en interruptions. Xenomai nous permet de régler beaucoup de paramètres pour ajuster au mieux le système au matériel cible.
PS: Je manque un peu de temps pour tenir le blog en ce moment, une partie non négligeable de mon temps libre étant consacré à l’exploration du Raspberry Pi (dont je reparlerai ici très prochainement bien sûr).
Hi,
It’s a great job of Xenomai latency utility.
I have few question about the calibration.
1. the target of calibration is to make « RTS lat min » approach to ZERO, am I right?
2. when I try to test kernel mode(Test mode: in-kernel periodic task), should I do it(re-calibrate) again?
Hi,