Vous avez raison de ne pas vous attendre à ce que les minuteries se déclenchent tôt - et elles ne le font pas. L'apparent le déclenchement précoce est dû au fait que vous ne mesurez pas le temps écoulé depuis l'expiration de la minuterie précédente - vous mesurez le temps depuis le précédent gettimeofday()
appel. S'il y a eu un délai entre l'expiration du minuteur et la planification du processus, vous verrez alors ce gettimeofday()
en retard, et le suivant en avance du même montant .
Au lieu de consigner la différence entre les gettimeofday()
suivants appels, essayez d'enregistrer les temps absolus renvoyés, puis comparez les temps renvoyés à N * 100 ms après le temps initial.
Si vous voulez PREEMPT_RT
pour vous aider, vous devrez définir une politique de planification en temps réel pour votre programme de test (SCHED_FIFO
ou SCHED_RR
), qui nécessite root.
J'ai apporté quelques modifications à votre code, et principalement remplacé le timer
comme suit et exécutez le processus en tant que progression RT (SCHED_FIFO).
setitimer() -> timer_create()/timer_settime()
gettimeofday() -> clock_gettime()
mon banc d'essai est un processeur i9-9900k et PREEMPT-RT patché Linux avec le noyau 5.0.21. L'intervalle de temps de la minuterie est de 1 ms et le programme s'exécute environ 10 heures pour générer le résultat suivant.
J'utilise aussi Cyclictest
(basé sur nanosleep()
) sur ma machine, et il montre un meilleur contrôle de la latence (latence maximale inférieure à 15us). Donc, à mon avis, si vous souhaitez réaliser vous-même une minuterie haute résolution, un thread RT autonome exécutant nanosleep sur un noyau isolé peut être utile. Je suis nouveau dans le système RT, les commentaires sont les bienvenus.