Le chapitre précédent suivait une instruction à travers ses étapes. Celui-ci regarde le matériel sur lequel ces étapes s’exécutent.
Dans un CPU, la partie qui contient et transforme les données est le chemin de données (datapath) : les registres, l’ALU qui calcule sur eux, et les bus qui transportent les valeurs entre les deux. Autour se trouvent l’unité de contrôle, qui décide à chaque cycle d’horloge ce que fait le chemin de données, et l’interface de bus, qui relie le CPU à la mémoire par le bus système.
Dans la vue CPU & buses du simulateur, le chemin de données est la moitié gauche du bloc CPU : register file, internal bus, ALU et AGU. La bus interface, avec son MAR et son MDR, fait la frontière entre le CPU et le bus système.
Le cycle du chemin de données
La plupart des instructions se ramènent au même court trajet : sortir deux valeurs des registres, les faire passer dans l’ALU, et ranger le résultat dans un registre. Ce trajet est le cycle du chemin de données, le cœur du CPU. Sa vitesse fixe en grande partie celle de la machine.
- mov eax, 5
- mov ebx, 7
- add eax, ebx
Le add prend sept micro-opérations, dont cinq forment le cycle du chemin de données :
- Fetch et 2. decode, comme pour toute instruction.
- Lecture de
eax(5) depuis le banc de registres sur le bus interne. - Lecture de
ebx(7) de la même façon. - ALU : 5 + 7 = 12, et les drapeaux sont mis à jour.
- Write-back : 12 dans
eax. - Suivante :
ripavance.
Aucun accès mémoire : 1 R · 0 W — seulement le fetch.
Un bus ou trois
Le simulateur fait passer les deux opérandes l’un après l’autre sur un seul bus interne. C’est une vraie conception : avec un seul bus, le premier opérande attend dans un registre tampon à l’entrée de l’ALU pendant que le second circule, et le résultat revient par le même bus. Peu de fils, mais plusieurs transferts par opération.
Les conceptions plus rapides donnent plusieurs bus au chemin de données : deux pour amener les opérandes à l’ALU en même temps, et un troisième pour ramener le résultat. Le banc de registres a alors besoin de deux ports de lecture et d’un port d’écriture : il peut fournir deux registres et en recevoir un dans le même cycle. Les cœurs x86 modernes vont bien plus loin, avec des bancs de registres à nombreux ports qui alimentent plusieurs ALU à la fois.
Ce qui se passe pendant un cycle d’horloge
add eax, ebx lit eax et écrit eax. Comment lire et écrire le même registre dans le même cycle sans mélanger l’ancienne et la nouvelle valeur ? Grâce au minutage. Dans une conception typique, un cycle d’horloge se déroule ainsi :
- L’unité de contrôle positionne les signaux de contrôle : quels registres alimentent les bus, quelle opération fait l’ALU, quel registre reçoit le résultat.
- Les registres choisis placent leur valeur sur les bus.
- L’ALU — un circuit combinatoire qui calcule en permanence — produit un résultat stable dès que ses entrées sont stables.
- Le résultat se propage jusqu’aux registres.
- Au front d’horloge, le registre de destination mémorise le résultat.
L’ancienne valeur de eax reste sur le bus pendant tout le cycle, et la nouvelle n’est rangée qu’à la toute fin. Lire et écrire le même registre dans un cycle est donc sans danger.
C’est aussi ce qui limite la fréquence d’horloge. La période d’horloge doit dépasser la somme des étapes 1 à 4 — le chemin le plus lent à travers le chemin de données. Raccourcissez ce chemin, ou découpez-le en morceaux, et l’horloge peut battre plus vite. Le découper en morceaux, c’est exactement ce que fait le pipeline, comme le montrera un prochain chapitre de ce niveau.
Calculer des adresses : l’AGU
Toutes les additions ne passent pas par l’ALU. Les opérandes mémoire comme [rbx+rcx*4+8] exigent d’abord un calcul d’adresse, et les CPU x86 ont pour cela une unité de génération d’adresses (AGU) dédiée. Elle peut travailler en même temps que l’ALU.
lea (load effective address) montre l’AGU seule. Elle calcule une adresse et la range dans un registre, sans toucher à la mémoire :
- mov rbx, 0x1000
- mov rcx, 3
- lea rax, [rbx+rcx*4+8]
L’AGU calcule 0x1000 + 3×4 + 8 = 0x1014, qui va directement dans rax. Aucun cycle sur le bus de données : 1 R · 0 W. C’est pourquoi les compilateurs utilisent souvent lea pour de l’arithmétique ordinaire, comme lea eax, [rdi+rdi*2] pour multiplier par 3.
Sortir du CPU : MAR et MDR
Pour atteindre la mémoire, le chemin de données passe par deux registres de l’interface de bus :
- le MAR (registre d’adresse mémoire) contient l’adresse et la place sur le bus d’adresses ;
- le MDR (registre de données mémoire) contient la donnée qui part vers la mémoire ou qui en revient, sur le bus de données.
- mov eax, 42
- mov DWORD PTR [rbp-8], eax
- mov edx, DWORD PTR [rbp-8]
La démo s’arrête après l’écriture : eax (42) est lu sur le bus interne, l’AGU calcule rbp − 8 = 0x7fffffd8, l’adresse va dans le MAR et la valeur dans le MDR, et l’unité de contrôle active MEMW. Soit 1 R · 1 W.
Appuyez sur Step pour la lecture : l’AGU calcule la même adresse, le MAR la place sur le bus, MEMR est activé, et la mémoire place 42 sur le bus de données, dans le MDR, qui l’envoie ensuite dans edx. Soit 2 R · 0 W : le fetch plus la lecture de la donnée.
Le bus système
Un bus est un ensemble de fils partagés auxquels plusieurs composants sont reliés. Le bus système regroupe ses lignes en trois ensembles :
| Lignes | Transportent | Sens |
|---|---|---|
| Adresses | quel emplacement mémoire ou quel périphérique | depuis le CPU (ou un autre maître) |
| Données | la valeur lue ou écrite | dans les deux sens |
| Contrôle | le type d’opération et son moment : lecture ou écriture, mémoire ou E/S, attente, interruption, horloge… | variable |
Les lignes de contrôle exactes dépendent du bus. Le simulateur utilise les noms du bus ISA, MEMR et MEMW. Beaucoup de bus de manuel utilisent une ligne MREQ (« ceci est un accès mémoire ») associée à RD et WR.
Largeur
Avec n lignes d’adresse, un bus peut sélectionner 2ⁿ emplacements différents. C’est un coût fixe : chaque ligne est un fil, une broche et une piste sur la carte. L’histoire d’Intel illustre le problème. Le 8088 du premier IBM PC avait 20 lignes d’adresse, donc pouvait adresser 1 Mo. Le 80286 a eu besoin de 24 lignes pour 16 Mo, et le 80386 de 32 lignes pour 4 Go. Chaque extension devait rester compatible avec la précédente.
La largeur du bus de données fixe le nombre de bits transférés à chaque fois. Le débit d’un bus vaut largeur × transferts par seconde, ce qui laisse deux façons de l’augmenter : élargir le bus, ou l’accélérer. Accélérer est difficile, car les signaux des différentes lignes n’arrivent pas exactement en même temps (décalage de bus, bus skew), et l’écart s’aggrave quand l’horloge monte.
Certains bus économisent des fils par multiplexage : les mêmes lignes transportent d’abord l’adresse, puis la donnée. Les 16 lignes AD0–AD15 du 8086 fonctionnaient ainsi. C’est moins cher mais plus lent, car adresse et donnée ne peuvent plus voyager ensemble.
Cycles de bus et états d’attente
Sur un bus synchrone, tout est cadencé par une horloge de bus, et chaque transfert dure un nombre entier de cycles de bus. Une lecture se déroule ainsi :
- Le CPU place l’adresse sur les lignes d’adresse.
- Il active les lignes de contrôle d’une lecture mémoire.
- Si la mémoire ne peut pas répondre à temps, elle active WAIT, et le CPU insère des états d’attente — des cycles de bus supplémentaires — jusqu’à ce qu’elle soit prête.
- La mémoire place la donnée sur les lignes de données, et le CPU la mémorise à un instant fixe du cycle, puis relâche les lignes de contrôle.
Par exemple, un bus à 100 MHz a des cycles de 10 ns. Une lecture prend alors un nombre minimal fixe de cycles, plus un cycle par état d’attente dont la mémoire a besoin.
Un bus asynchrone n’a pas d’horloge maîtresse. Les deux côtés utilisent à la place une poignée de main (handshake) : le maître signale « adresse et commande prêtes », l’esclave répond « donnée prête », le maître acquitte, et l’esclave relâche. Chaque transfert dure exactement le temps dont cette paire de composants a besoin. C’est plus souple, mais plus difficile à concevoir.
Maîtres, esclaves et arbitrage
Le composant qui lance un transfert est un maître, celui qui répond un esclave. Le CPU est généralement le maître et la mémoire l’esclave. La mémoire est toujours esclave. Mais d’autres composants peuvent aussi être maîtres. Un contrôleur de disque ou de réseau qui fait du DMA (direct memory access, accès direct à la mémoire) écrit en mémoire de lui-même, sans que le CPU copie chaque mot.
Quand plusieurs maîtres veulent le bus au même instant, quelqu’un doit choisir. C’est l’arbitrage de bus :
- Dans l’arbitrage centralisé, un arbitre unique accorde le bus. Avec le chaînage (daisy chaining), le signal d’accord passe de composant en composant, et le premier qui veut le bus le garde : la position d’un composant fixe donc sa priorité.
- Dans l’arbitrage décentralisé, les composants se départagent entre eux via des lignes de requête partagées.
Les bus dans un PC moderne
Le bus système unique et partagé appartient surtout au passé. Depuis le milieu des années 2000 — l’Athlon 64 d’AMD en 2003, le Nehalem d’Intel en 2008 — le contrôleur mémoire est intégré à la puce du CPU. La mémoire est atteinte par des canaux DDR dédiés : 64 bits de données par canal DDR4, et deux sous-canaux indépendants de 32 bits par module DDR5. Les périphériques sont reliés par PCI Express, qui, malgré son nom, n’est pas du tout un bus. C’est un ensemble de lignes (lanes) série point à point (x1, x4, x16…) qui transportent des paquets. Et à l’intérieur de la puce, cœurs et caches communiquent par une interconnexion en anneau ou en maillage.
Le modèle de ce chapitre reste valable dans tout cela. Chaque transfert a toujours une adresse, une donnée et une commande de lecture ou d’écriture — seuls les fils qui les transportent ont changé.
À retenir
- Le chemin de données, ce sont les registres, l’ALU et les bus qui les relient. Le cycle du chemin de données — lire les registres, calculer, écrire le résultat — est le cœur du CPU.
- Les registres sont lus tôt dans le cycle et écrits au front d’horloge, donc une instruction peut lire et écrire le même registre. Le chemin le plus lent fixe la période d’horloge.
- L’AGU calcule les adresses ;
leal’utilise sans toucher à la mémoire. - Le MAR et le MDR relient le chemin de données aux bus d’adresses et de données, et les lignes de contrôle indiquent le type de transfert.
- La largeur du bus limite la mémoire adressable et la quantité de données par transfert. Les composants lents ajoutent des états d’attente, et l’arbitrage décide quel maître utilise le bus.