Conseils sur le développement sous Linux

L’ordonnanceur POSIX fait au mieux

Note

Le POSIX scheduler ne propose que du best effort et le noyau Linux cherche à optimiser la bande passante.

En conséquence dans un système multi processeur (SMP) le noyau va privilégier l’exécution d’un thread de moindre priorité si cela lui permet d’éviter une migration.

Prenons l’exemple suivant de deux processeurs ayant dans leur file d’attente des threads de priorité 90, 80, 70 et 95, 85, 75.

Les threads de priorité 90 et 95 sont RUNNING respectivement sur les CPU 0 et 1. Les autres threads ayant été actifs par le passé, les caches des CPUs contiennent des entrées pour 90, 80 et 70 sur le cache_0 et pour 95, 85 et 75 sur le cache_1

CPU0

CPU1

90

95

80

85

70

75

Si maintenant le process de priorité 90 se termine sur le CPU0 le respect à la lettre de POSIX voudrait que le thread 85 prenne sa place.

Cependant le cache du CPU0 ne contient pas d’entrée pour le thread 85 et migrer ce thread du cache_1 vers le cache_0 implique de:

  1. flusher les entrées appartenant au thread 85 du cache_1 vers la mémoire

  2. flusher certaines entrées du cache_0 pour faire de la place

  3. charger au moins une entrée du thread 85 de la mémoire vers le cache_0

  4. les autres entrées du thread 85 seront chargées à la demande

CPU0

CPU1

80

95

70

85

60

75

Pendant ce temps qui peut être assez long suivant l’architecture mémoire, il est fort probable que le thread 95 du CPU1 ait fini son travail et le thread 85 si il n’avait pas migré aurait trouvé un cache_1 chaud.

En conclusion

Il ne faut jamais tenir compte de la priorité d’un thread POSIX temps réel FIFO ou RR pour estimer si un thread gagnera un CPU avant un autre.

Pour cela il faudra utiliser un mécanisme de synchronisation comme les pthread_mutex(3) ou les futex.