« Fonctionnement d'un ordinateur/Architectures multiprocesseurs et multicœurs » : différence entre les versions

m
Les processeurs Haswall supportent aussi le ''Speculative Lock Elision''. Les instructions atomiques peuvent être transformée en transaction à une condition : qu'on leur rajoute un préfixe. Le préfixe d'une instruction x86, correspond à un octet optionnel, placé au début de l'instruction. Il donne des indications au processeur, qui permettent de modifier le comportement de l'instruction. Le préfixe LOCK rend certaines instructions atomiques, REPNZE répéte certaines instructions tant qu'une condition est requise, etc. Le fait est que certains préfixes n'ont pas de signification pour certaines instructions. Autrefois, les préfixes sans signification étaient totalement ignorés par le processeur. Pour supporter le Lock Elision, ces préfixes sans significations sont réutilisés pour indiquer qu'une instruction atomique doit subir la Lock Elision. De plus, deux "nouveaux" préfixes font leur apparition : XAQUIRE qui sert à indiquer que notre instruction atomique doit être tentée en tant que transaction ; et XRELEASE qui dit que la transaction spéculative est terminée. Ainsi, un programme peut être conçu pour utiliser la Lock Elision, tout en fonctionnant sur des processeurs plus anciens, qui ne la supportent pas ! Belle tentative de garder la rétrocompatibilité.
 
==ConsistanceLa consistance mémoire==
 
On a vu dans les chapitres précédents que les processeurs modernes modifient l'ordre des accès mémoire pour gagner en efficacité. Avec plusieurs processeurs, chaque processeur fait cela chacun dans son coin sans se préoccuper des autres. Les opérations d'écriture peuvent être mises dans le désordre du point de vue des autres processeurs, et les lectures effectuées par les autres processeurs peuvent alors renvoyer de vielles données. Pour que les accès mémoires dans le désordre ne posent pas de problèmes, il existe différentes solutions.
{|class="wikitable"
|-
! Modèle de consistance
! Description
|-
! Consistance séquentielle
| Aucune réorganisation de l'ordre des instructions n'est possible. Tout se passe comme si les instructions de chaque programme s'effectuaient dans l'ordre imposé par celui-ci, et que les lectures ou écritures des différents processeurs étaient exécutées les unes après les autres. Ce modèle de consistance interdit de nombreux cas de réorganisation parfaitement légaux, même avec plusieurs processeurs.
|-
! Total Store Ordering
| Un processeur peut immédiatement réutiliser une donnée qu'il vient d'écrire dans son cache. Tout se passe donc comme si l'écriture en question n'était pas in-interruptible : on peut lire la donnée écrite avant que toutes les versions de la donnée soient mises à jour. C'est ce qui était fait dans les protocoles de cohérence des caches qu'on a vus précédemment : le statut modified n’empêchait pas les lectures de la donnée.
|-
! Partial Store Ordering
| Permet des écritures simultanées, ainsi que des réorganisations de l'ordre des écritures qui portent sur des données différentes. Ainsi, on peut démarrer une nouvelle écriture avant que les écritures précédentes ne soient terminées. La seule condition pour éviter les catastrophes est que ces écritures manipulent des données différentes, placées à des endroits différents de la mémoire.
|-
! No Store Ordering
| Toutes les réorganisations possibles entre lectures et écritures sont autorisées, tant qu'elles se font sur des données différentes. On peut parfaitement démarrer une lecture pendant que d'autres sont en attente ou en cours.
|}
 
===FencesLes fences et barrières mémoires===
 
Les processeurs à type ''No Store Ordering'' garantissent que les accès à des données partagées se déroulent correctement avec des instructions que doivent utiliser les compilateurs ou les programmeurs : des Memory Barriers, ou '''Fences'''. Ce sont des instructions qui vont forcer le processeur à terminer toutes les écritures et/ou lectures qui la précède. Pour plus d'efficacité, certains processeurs possèdent deux Fences : une pour les lectures, et une autre pour les écritures. Certains processeurs utilisent un nombre de Fences plus élevé, et peuvent ainsi avoir des fences dédiées à des cas particuliers.
 
[[File:Fences.png|centre|vignette|upright=2|Fences.]]
 
Le placement des fences dans un programme est géré par un subtil équilibre entre programmeur et compilateur. Généralement, un compilateur peut placer ces Fences au bon endroit, avec un peu d'aide du programmeur. Certains langages de programmation permettent d'indiquer au compilateur qu'une donnée doit toujours être lue depuis la mémoire RAM, via le mot-clé volatile. C'est très utile pour préciser que cette donnée est potentiellement partagée par plusieurs processeurs ou manipulable par des périphériques. Les compilateurs peuvent placer des Fences lors des lectures ou écritures sur ces variables, mais ce n'est pas une obligation. Il arrive aussi que le programmeur doive manipuler explicitement des Fences. Utiliser l'assembleur est alors une possibilité, mais qui est rarement exploitée, pour des raisons de portabilité. Pour limiter la casse, certains systèmes d'exploitations ou compilateurs peuvent aussi fournir des Fences explicites, encapsulées dans des bibliothèques ou cachées dans certaines fonctions.
 
Après avoir vu la théorie, passons maintenant à la pratique. Dans cette partie, on va voir les modèles de consistances utilisés sur les processeurs x86, ceux qu'on retrouve dans nos PC actuels. Le modèle de consistance des processeurs x86 a varié au cours de l'existence de l'architecture : un vulgaire 486DX n'a pas le même modèle de consistance qu'un Core 2 duo, par exemple. Quoi qu’il en soit, les modèles de consistance des processeurs x86 ont toujours étés assez forts, avec pas mal de restrictions. Si on compare aux autres processeurs, le x86 est assez strict. Bref, le premier modèle de consistance utilisé sur les processeurs x86 est apparu sur les premiers processeurs x86 et est resté en place sur tous les processeurs de marque Pentium. Ce modèle est assez simple : hormis une exception, tout doit se passer comme si le processeur accédait à la mémoire dans l'ordre des opérations de notre programme. Cette exception concerne les lectures : dans certains cas, on peut les exécuter avant certaines écritures, sous réserve que les conditions suivantes soient respectées :
 
* ces écritures doivent se faire dans la mémoire cache ;
* la lecture doit se faire dans la mémoire ;
* aucune transaction avec un périphérique ne doit être en cours.
 
Sur les processeurs à partir du Pentium 4, les choses changent. Le Pentium 4 est en effet le premier processeur à implémenter des techniques permettant d’exécuter plusieurs processus en parallèle. Ce processeur est en effet le premier à utiliser l'Hyperthreading. En conséquence, le modèle de consistance a du être assoupli pour éviter de perdre bêtement en performance. Voici un résumé de ce modèle de consistance :
Voici un résumé de ce modèle de consistance :
 
* une lecture ne peut pas être déplacée avant ou après une autre lecture ;
* une écriture ne peut pas être déplacée avant une lecture ;
39 538

modifications