Mémoire et processeur
Progression
#Mémoire et processeur
La hiérarchie mémoire constitue un élément essentiel de l'architecture des ordinateurs modernes, conçue pour nourrir le processeur en données et instructions malgré la relative lenteur de la mémoire principale. Cette architecture en couches s'étend des registres ultrarapides jusqu'à la RAM, en passant par plusieurs niveaux de cache (L1, L2, L3). La compréhension de cette hiérarchie, du TLB pour la traduction d'adresses, de la cohérence de cache entre cœurs, et des techniques pour optimiser la localité des accès mémoire permet d'écrire du code significativement plus performant.
Objectifs d'apprentissage
- Décrire la hiérarchie mémoire (registres, L1, L2, L3, RAM) et comprendre l'impact des cache-miss sur les performances.
- Expliquer le rôle du TLB dans l'adressage virtuel, ainsi que les notions de pages, fautes mineures et majeures.
- Comprendre les mécanismes de cohérence de cache (comme MESI) et le phénomène de false sharing sur architectures multi-cœurs.
- Appliquer des principes de localité et de réduction des branchements pour optimiser les performances.
#Hiérarchie mémoire
La hiérarchie mémoire équilibre vitesse et capacité à travers plusieurs niveaux : les registres du processeur offrent un accès quasi-instantané, suivis des caches L1, L2 et L3 de plus en plus grands mais légèrement plus lents, puis de la RAM, et finalement du disque. Le matériel exploite les principes de localité temporelle (réutilisation récente) et spatiale (accès à des adresses voisines) en chargeant les données par lignes de cache complètes. Les stratégies d'écriture, qu'elles soient write-back (écriture différée en mémoire) ou write-through (écriture immédiate), influencent également les performances. Optimiser un parcours de données revient essentiellement à respecter cette localité pour maximiser les hits dans les caches rapides.
Registre/L1: ~0.5–4 ns • L2: ~7–15 ns • L3: ~20–40 ns • RAM: ~60–120 ns. Les valeurs réelles varient selon CPU et fréquences. L'important: l'écart de plusieurs ordres de grandeur entre registres/caches et RAM.
#Exécution
Le pipeline d'instructions, la prédiction de branchement et l'exécution hors-ordre sont des techniques qui maintiennent le processeur constamment occupé. Cependant, un cache-miss profond ou une mauvaise prédiction de branchement peuvent faire chuter dramatiquement l'IPC (instructions par cycle) et augmenter la latence effective. Sur des parcours mémoire irréguliers, le coût des ratés de TLB (Translation Lookaside Buffer) s'ajoute à celui des ratés de cache, aggravant encore la pénalité de performance.
#Expérience: localité de cache (Python)
Cette démo Pyodide illustre la localité, mais les chiffres absolus diffèrent du natif. Retenez la tendance: parcours séquentiel exploite mieux les caches.
#Simulateur : hiérarchie et miss ratio
Hiérarchie mémoire — simulateur
Ajustez la taille d’ensemble de travail, le pas d’accès et le nombre de threads pour estimer la répartition des hits dans la hiérarchie cache et l’impact sur la latence moyenne.
Ensemble de travail
256 KB
Volume de données actives que le code parcourt en boucle.
Stride / pas d’accès
×8
Distance entre deux accès consécutifs (1 → séquentiel).
Threads concurrents
1
Plus de threads ⇒ compétition sur les caches partagés.
Prélecture matérielle
La prélecture est bénéfique pour les accès réguliers; sur accès aléatoires, elle gaspille de la bande passante.
Répartition des hits
Latence moyenne estimée
43.9 ns
Combinaison pondérée hits caches + accès DRAM
Bande passante effective
120.0 Go/s
Hypothèse: ligne de cache 64 B
La majorité des accès (47%) finit en DRAM. Réduisez l’ensemble chaud (actuellement 256 KB) ou améliorez la localité (stride 8).
Profils d’accès
- Localité spatiale : stride 1 exploite les lignes de cache; un stride élevé saute des blocs entiers.
- Localité temporelle : petits working sets revisitent les mêmes lignes → hits L1/L2.
- Contention : plusieurs threads partagent L3/DRAM → miss ratio augmente.
- Prélecture : utile si l’accès est régulier; nuisible sinon.
Cette simulation reste indicative mais permet de raisonner: réduisez l’ensemble de travail « chaud », regroupez les données et préférez des parcours séquentiels pour que les caches fassent leur travail.
#Conseils de performance
Pour exploiter efficacement la hiérarchie mémoire, privilégiez les parcours séquentiels et les structures de données contiguës qui bénéficient naturellement de la localité spatiale. Groupez les champs fréquemment accédés ensemble dans vos structures et limitez l'empreinte mémoire « chaude » (l'ensemble des données activement utilisées) pour qu'elle tienne dans les caches. Les préfetchs (chargements anticipés) explicites n'apportent un bénéfice que si le pattern d'accès est prévisible et suffisamment en avance ; dans le cas contraire, ils gaspillent de la bande passante mémoire. Sur les architectures multi-cœurs, évitez le false sharing en séparant les données écrites concurremment par différents threads, afin d'éviter des invalidations de cache coûteuses.
Deux threads écrivant sur des variables différentes mais dans la même ligne de cache se ralentissent par invalidations (cohérence MESI). Aligner/séparer les données écrites fréquemment.
#Mémoire virtuelle et TLB (aperçu)
L'adressage virtuel découpe la mémoire en pages (typiquement 4 Ko) et le TLB met en cache les traductions d'adresses virtuelles vers physiques. Un raté de TLB est coûteux car il nécessite une marche dans les tables de pages, et s'ajoute aux éventuels ratés de cache. Les accès mémoire irréguliers et les ensembles de travail trop grands pénalisent fortement les performances en multipliant ces ratés. L'utilisation de structures contiguës, une bonne réutilisation spatiale et temporelle, et parfois le recours aux huge pages (pages de grande taille) peuvent améliorer significativement la situation. Sur les systèmes SMP (multiprocesseurs symétriques), les invalidations de TLB inter-cœurs (appelées « TLB shootdowns ») expliquent certaines pauses observées lors de changements de mappings mémoire.