Selon Microsoft, ce genre de machine est prévue pour une utilisation en centre informatique, dans un futur pas trop lointain. On peut penser à certains clients d’Azure, notamment dans le secteur de la défense, qui exigent des machines qui leur sont exclusivement réservées. Il n’empêche que ce genre de machines n’est plus aussi courante qu’auparavant, vu l’explosion du nombre de cœurs par processeur : avant 2010, les processeurs montaient à huit cœurs, il n’était pas déraisonnable d’en assembler huit dans une machine, pour monter à trente-deux ou soixante-quatre cœurs ; aujourd’hui, les processeurs x86 montent jusque vingt-huit (Intel) ou trente-deux (AMD) cœurs, ce qui limite le besoin de ces configurations.
On peut néanmoins se demander comment Microsoft arrive à de tels nombres de processeurs par machine : Intel présente ses Xeon 8180 comme prévu pour huit sockets par machine, non trente-deux. Pour ce faire, la solution avancée par Intel est d’utiliser les trois liens QPI fournis par chaque processeur pour l’interconnexion : chaque processeur est directement connecté à trois autres ; les quatre derniers processeurs doivent passer par une étape intermédiaire pour la communication.
La seule solution imaginable est de se rapprocher des réseaux informatiques : au lieu de connecter directement les processeurs entre eux, on peut les relier à des commutateurs QPI. Cette solution permet d’augmenter le nombre de processeurs par machine, mais au prix d’une latence plus élevée : il faut traverser plus d’équipements avant d’atteindre le processeur cible. Ce genre de solution est déjà utilisée pour les superordinateurs, mais pas au niveau d’une même machine : des cartes réseau extrêmement performantes sont connectées à chaque processeur (comme InfiniBand), avec des débits très élevés (de l’ordre de cinquante gigabits par seconde par lien en Infiniband EDR) et des latences très faibles (une demi microseconde ajoutée par chaque adaptateur réseau, toujours pour Infiniband EDR). Des liens QPI pourraient être plus rapides encore, vu qu’ils ne doivent pas s’étendre sur plusieurs dizaines de mètres, mais uniquement à l’intérieur d’un boîtier.
Revenons à Windows. Comment le noyau peut-il gérer autant de cœurs ? Surtout que, selon Microsoft, le même noyau est utilisé pour toutes les machines Windows : des Surface RT, avec des processeurs ARM assez peu puissants (NVIDIA Tegra), jusqu’aux plus grosses machines virtuelles disponibles sur Azure (plus de septante cœurs). Les difficultés proviennent de l’ordonnanceur utilisé, c’est-à-dire la partie du noyau qui se charge de décider quel fil d’exécution de quel processus utilise quels cœurs et à quels moments. Windows utilise un ordonnanceur préemptif avec des priorités : chaque fil d’exécution dispose de sa propre priorité ; le fil qui a la plus haute priorité est exécuté en priorité, quitte à arrêter l’exécution d’un autre fil avant qu’il ait terminé (ce qu’on appelle la préemption). Par exemple, un processus interactif aura une priorité plus grande qu’un processus qui effectue principalement des calculs ou des opérations d’entrée-sortie : quand l’utilisateur clique sur un bouton, il veut que l’application réagisse de suite, pas quand tous les calculs à effectuer sont réalisés.
Pour ce faire, l’ordonnanceur a évolué au fil des années, en passant d’une seule file de fils d’exécution prêts à être exécutés (Windows 2000) à une file par processeur (Windows 2003). Cette solution ne garantit pas que tous les processus prioritaires sont exécutés rapidement, mais uniquement par processeur — ce qui fonctionne assez bien quand les cœurs disponibles sont assez rapides, mais pas sur des tablettes. Une idée sous-jacente est que, si un processus change en permanence de processeur ou de cœur, ce cœur devra recharger des données depuis la mémoire centrale au lieu d’utiliser ses caches. La solution suivante a été d’utiliser une file par processeur (des files réservées aux processus qui ont une affinité avec un cœur de calcul en particulier) plus une file partagée pour les tâches interactives (Windows 8.1).
En parallèle, l’ordonnanceur a commencé à implémenter des mécanismes d’équité entre les utilisateurs (Windows 7), en plus de la priorité : si un utilisateur utilise énormément les ressources de calcul avec des fils d’exécution à haute priorité, les autres utilisateurs (qui lancent des tâches avec une priorité moindre) ne devraient pas trop le ressentir.
Ces solutions ont assez bien fonctionné jusqu’au moment où certaines applications gourmandes, comme un serveur SQL, utilisent plus de soixante-quatre cœurs. Le problème était que le nombre de fils d’exécution tentant d’être ordonnancés était trop élevé, alors que tout le monde tentait d’utiliser la même ressource : il fallait donc attendre que cette ressource soit disponible avant d’exécuter des instructions. Ces ressources sont extrêmement présentes : des événements, des sémaphores, des entrées-sorties, etc. Un des gros apports de Windows 7 a été la gestion plus fine des verrous sur ces ressources : au lieu d’un verrou global, chaque ressource est verrouillée indépendamment des autres. Windows 10 a continué ces améliorations avec le partitionnement des groupes de processeurs : certains processus ont un accès exclusif à un groupe de processeurs/cœurs, que les autres processus ne pourront plus utiliser. C’est notamment grâce à cela que le mode Jeu fonctionne pour améliorer la performance d’une application en particulier : l’utilisateur n’est pas intéressé par les autres applications pendant un certain temps, ces dernières devront donc se partager quelques miettes restantes de puissance de calcul.
Finalement, avec Windows 10 pour ARM, une dernière fonctionnalité a dû être ajoutée : l’ordonnancement hétérogène. Bon nombre de processeurs ARM sont conçus avec une architecture big.LITTLE : certains cœurs sont très puissants, mais consomment énormément d’énergie. Pour garantir une bonne réactivité et économiser de la batterie, Windows ordonnance donc les processus les moins importants sur les cœurs les moins puissants (l’API Windows propose d’ailleurs un mécanisme pour marquer un processus comme peu important).
Ce n’est que grâce à toutes ces techniques et à leurs raffinements successifs que Windows arrive à gérer autant de cœurs, dans des architectures aussi hétérogènes.
Sources : One Windows Kernel, 896 Xeon Cores in One PC: Microsoft’s New x86 DataCenter Class Machines Running Windows.