Quelle est l'origine de l'imprévisibilité de la durée d'exécution d'une séquence d'instructions ?
Est-ce principalement lié aux pipelines, aux caches, à l'exécution dans le désordre et au prédicteur de branchement ?
À toutes ces choses là, exactement, auxquelles il faut aussi ajouter :
la différence entre la fréquence du processeur et la fréquence du bus mémoire (pouvant occasionner un délai de synchronisation entre les deux lors des accès mémoire) ;
la variation de la fréquence du processeur dans le temps ;
les fonctionnalités d’économie d’énergie ;
le déplacement du processus d’un processeur à un autre ;
les interruptions matérielles.
On peut facilement toucher du doigt cette imprévisibilité avec le petit test suivant :
Même s’il semble clairement y avoir un biais en faveur de valeurs proches de ~1000, la variabilité est quand même bien là.
Évidemment, plus la séquence d’instruction exécutée dans la boucle est longue et complexe, et plus sa durée d’exécution sera variable. Dans le noyau, c’est carrément l’ordonnanceur du système qui est appelé dans la boucle entre deux lectures du compteur, de sorte qu’à la variabilité du processeur lui-même s’ajoute celle du système (qui va varier en fonction de la charge, des activités en provenance des périphériques, etc.).
[^] # Re: Question sur le jitter entropy
Posté par gouttegd . En réponse à la dépêche Des nombres aléatoires dans le noyau Linux. Évalué à 8.
À toutes ces choses là, exactement, auxquelles il faut aussi ajouter :
On peut facilement toucher du doigt cette imprévisibilité avec le petit test suivant :
Un exemple d’exécution chez moi :
$ ./a.out
Δ TSC: 28
Δ TSC: 86490
Δ TSC: 1728
Δ TSC: 1114
Δ TSC: 37814
Δ TSC: 1096
Δ TSC: 982
Δ TSC: 1240
Δ TSC: 1020
Δ TSC: 976
Même s’il semble clairement y avoir un biais en faveur de valeurs proches de ~1000, la variabilité est quand même bien là.
Évidemment, plus la séquence d’instruction exécutée dans la boucle est longue et complexe, et plus sa durée d’exécution sera variable. Dans le noyau, c’est carrément l’ordonnanceur du système qui est appelé dans la boucle entre deux lectures du compteur, de sorte qu’à la variabilité du processeur lui-même s’ajoute celle du système (qui va varier en fonction de la charge, des activités en provenance des périphériques, etc.).