1 - Free

publicité
Architecture des ordinateurs
L’3 EFREI - 2009/2010
N. Sicard
Architecture des ordinateurs
Architecture : “organisation des éléments composant un
système informatique”
Ordinateur : “machine électronique de traitement numérique
de l’information, exécutant à grande vitesse les instructions
d’un programme enregistré”
Petit Robert
© EFREI 2009 - Nicolas Sicard
2
“People who are really serious about software
should make their own hardware”
Alan Kay
© EFREI 2009 - Nicolas Sicard
3
Pourquoi ?
Architectures spécialisées / embarquées
Programmation des systèmes d’exploitation
Optimisations logicielles : 1 à 2 ordres de grandeur
Nouvelles architectures : multi-cœurs / reconfigurables / GPGPU
© EFREI 2009 - Nicolas Sicard
4
Références
Cours d’architecture des ordinateurs L2 de N. Flasque (EFREI)
Cours d’architecture des ordinateurs de Christophe Fiorio
(Polytech’ Montpellier)
Wikipedia (Architecture des ordinateurs)
Architecture des ordinateurs : une approche quantitative Henessy/Patterson - Vuivert / 3ème édition
Architecture des ordinateurs - Andrew Tanenbaum - Pearson
Education
© EFREI 2009 - Nicolas Sicard
5
Petit historique
Logique
mathématique
Mécanique
Automatique
Électromécanique
Électronique
XIXe
Boole (1850)
XXe
Babbage (1834)
Shannon
ENIAC (1944)
Turing (1940)
Von Neumann (1944)
Le transistor (Bell Labs, 1947)
© EFREI 2009 - Nicolas Sicard
6
Schéma général
E/S
Unité centrale de
traitement (CPU)
Registres
Unité de
commande
Unité arithmétique
& logique
(UAL)
programme
➁
Mémoire
centrale
(principale)
données
➂
➀
Périphériques
© EFREI 2009 - Nicolas Sicard
7
Principe de fonctionnement
1. Chargement du programme et des données dans la mémoire
centrale depuis un périphérique
2. Chargement séquentiel des instructions du programme de la
mémoire vers l’unité de commande
3. Analyse de l’instruction par l’unité de commande /
transmission à l’UAL pour traitement
4. Traitement de l’instruction par l’UAL (avec éventuellement
échanges avec la mémoire ou les périphériques)
© EFREI 2009 - Nicolas Sicard
8
Plan du cours
L’information
L’unité de traitement
La hiérarchie mémoire
Les bus
© EFREI 2009 - Nicolas Sicard
9
L’information
© EFREI 2009 - Nicolas Sicard
10
Codage de l’information
Ordinateur = “machine électronique de
traitement numérique de l’information...”
Information de base = le nombre (entier ou réel)
Comment représenter, traiter et stocker un
nombre ?
© EFREI 2009 - Nicolas Sicard
11
Représentation > Langage binaire
Alphabet de l’ordinateur = { 0, 1 }
Une lettre = un bit (unité d’information élémentaire)
Un mot = { bits } (un ensemble de bits de taille fixe)
L’information de base est un nombre codé par un mot
- entiers naturels (non signés)
- entiers signés (positifs ou négatifs)
- nombre réel “à virgule” (fixe ou flottante)
© EFREI 2009 - Nicolas Sicard
12
Langage binaire > Rappel sur les bases
Tout nombre P peut s’écrire dans une base b quelconque sous la forme :
an an−1 . . . a0 , a−1 . . . a−m
avec m, n > 0 et 0 ≤ ai < b
( ai = chiffre )
b
Nom
Chiffres
2
Binaire
{0,1}
8
Octale
{0,1,2,3,4,5,6,7}
10
Décimale
{ 0,1,2,3,4,5,6,7,8,9 }
16
Hexadécimale
{0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F}
base puissance de 2
© EFREI 2009 - Nicolas Sicard
13
Rappel sur les bases > Conversions
Conversion de la base b vers la base 10 :
an an−1 . . . a0 , a−1 . . . a−m
La valeur de P en base 10 est donnée par :
=
P
=
n
�
ai bi
i=−m
an bn +
an−1 bn−1 + . . . + a0 b0 + a−1 b−1 + . . . + a−m b−m
Exemple : valeur de P = (1011,110)2 en base 10 ?
Chiffres ai
a3
a2
a1
a0
,
a-1
a-2
a-3
Valeurs des ai
1
0
1
1
,
1
1
0
Puiss. de b (i)
3
2
1
0
-1
-2
-3
bi
8
4
2
1
0.5 0.25 0.125
© EFREI 2009 - Nicolas Sicard
P = 1x8 + 0x4 + 1x2 + 1x1 +
1x0,5 + 1x0,25 + 0x0,125
= 11,7510
14
Rappel sur les bases > Conversions > Exemples
Octal : (625,702)8 => base 10
Chiffres ai
a2
a1
a0
,
a-1
a-2
a-3
Valeurs des ai
6
2
5
,
7
0
3
Puiss. de b
2
1
0
-1
-2
-3
bi
64
8
1
0.125 0.015625 0.001953125
625,7028 = 6x64 + 2x8 + 5x1 + 7x0,125 + 0x0,015625 + 3x0,001953125
= 405,8789062510
Hexadécimal : (F23,A0)16 => base 10
Chiffres ai
a2
a1
a0
,
a-1
a-2
Valeurs des ai
F
2
3
,
A
0
Puiss. de b
2
1
0
-1
-2
bi
256
16
1
0.0625
0.00390625
F23,A016 = 15x256 + 2x16 + 3x1 + 10x0,0625 + 0x0,00390625
= 3875,62510
© EFREI 2009 - Nicolas Sicard
15
Rappel sur les bases > Conversions > Exemples
Conversions entre bases puissances de 2
Il suffit de regrouper ou séparer les bits :
‣ 3 bits = un chiffre octal
‣ 4 bits = un chiffre hexadécimal
Exemple :
1 0 0 1 1 1 , 1 0 1 1 0 1 1
Binaire
100
111
,
101
101
100
4
7
,
5
5
4
Octal
Binaire
Hexa
1 0 0 1 1 1 , 1 0 1 1 0 1 1
.0010
.0111
,
1011
.0110
2
7
,
B
6
© EFREI 2009 - Nicolas Sicard
16
Rappel sur les bases > Conversions > Exemples
Conversion depuis la base 10 vers la base b:
On divise le nombre en base 10 successivement par b tant que le quotient
est différent de 0. Les restes successifs (< b) constituent la suite des
chiffres en base b.
Exemple :
Nombre
Division
Quotient
Reste
163
/2 =
81
1
81
/2 =
40
1
40
/2 =
20
0
20
/2 =
10
0
10
/2 =
5
0
5
/2 =
2
1
2
/2 =
1
0
1
/2 =
0
1
© EFREI 2009 - Nicolas Sicard
16310 = 101000112
Lecture
du résultat
17
Langage binaire > Mots
Taille (en bits)
Nom français
English name
Nb de valeurs
représentables
1
bit
bit
2
4
quartet
nibble
24 = 16
8
octet
byte
28 = 256
16
mot de 16 bits
half-word
216 = 65536
32
mot de 32 bits
(32 bits) word
232 = 4,29.109
64
mot de 64 bits
(64 bits) word
264 = 1,84.1019
Espace de représentation pour des entiers naturels p (avec n bits) :
0 = (0...0)2 ≤ p ≤ 2n-1 = (1...1)2
© EFREI 2009 - Nicolas Sicard
18
Langage binaire > Poids des mots
Bits de poids fort / faible (sur N bits) :
1
0
0
1
1
1
1
0
0
1
0
1
0
bit de poids fort
(Most Significant Bit)
x2N-1
0
0
1
1
1
1
1
bit de poids faible
(Least Significant Bit)
x20
Octets de poids fort / faible :
1
0
1
octet de poids fort : x2N/2
0
0
1
0
1
0
0
1
1
octet de poids faible : x20
On peut généraliser aux mots de poids fort / faible dans les structures
plus grandes
© EFREI 2009 - Nicolas Sicard
19
Langage binaire > Addition simple
Exemple : additionner 18 et 27 en binaire
1
Rappel en décimal :
1
En binaire :
1 0 0 1 02
1 1 0 1 12
1 8
2 7
4 5
1
1 0 0 1 0
1 1 0 1 1
1 0 1 1 0 1
© EFREI 2009 - Nicolas Sicard
45
10
20
Langage binaire > Entiers signés
Bit de poids fort : bit de signe = 0 (positif) ou 1 (négatif)
0xxxxxxxx xxxxxxxx = (-1)0.p = +p
1xxxxxxxx xxxxxxxx = (-1)1.p = -p
p
Espace de représentation (restent n-1 bits)
-2n-1+1 ≤ p ≤ +2n-1-1
Problème : double représentation de 0
0 | 0...0 = +0
1 | 0...0 = -0
© EFREI 2009 - Nicolas Sicard
21
Entiers signés > Bit de signe simple
Problème au niveau des opérations (sur 5 bits) :
1
1
1
0 1 1 0 0
+ 1 1 1 0 0
[1] 0 1 0 0 0
12
-1 2
+8 ?!!
Représentation non consistante : phase d’interprétation de
l’instruction en fonction du signe (compliqué)
© EFREI 2009 - Nicolas Sicard
22
Entiers signés > Complément à 2
Principe général en base b (complément à b) :
Pour un nombre N en base b contenant n chiffres (n fixe), on appelle
complément à b de N le nombre N = bn - N.
On code la valeur -N par N.
Exemple en base 10 sur 5 chiffres :
Complément de 0 = 105 - 0 = (1)00000 = 00000 (tronqué à 5 chiffres) = 0
=> une seule représentation de 0 = 00000
Opérations sur n chiffres (exemple de l’addition) :
-N + N = N + N = (10n - N) + N = 10n = 0
si n=1 : -7 + 9 = (101 - 7) + 9 = 3 + 9 = (1)2 = 2 (tronqué à 1 chiffre)
si n=2 : -7 + 9 = (102 - 7) + 9 = 93 + 9 = (1)02 = 2 (tronqué à 2 chiffre)
© EFREI 2009 - Nicolas Sicard
23
Entiers signés > complément à 2
En base 2 (représentation binaire d’un nombre p) :
sur n bits : -p = 2n - p
Obtenir rapidement la représentation de -p à partir de p :
−p
=
=
2n − p = (2n − 1) + 1 − p
. . 1� −p + 1
�1 .��
n
=
Exemple (sur 5 chiffres) :
p+1
avec p = complémentaire (bit à bit) de p
p = 12 = 011002
-p = p + 1 = 10011 + 1 = 10100
Remarque : -(-p) = 01011 + 1 = 01100 = 12
=> la méthode est valable quelque soit le signe de départ !
© EFREI 2009 - Nicolas Sicard
24
Entiers signés > complément à 2
Application sur les opérations (sur 5 bits) :
1
1
1
0 1 1 0 0
+ 1 0 1 0 0
[1] 0 0 0 0 0
12
-1 2
0
Représentation consistante : pas de phase d’interprétation
supplémentaire pour les nombres signés
© EFREI 2009 - Nicolas Sicard
25
Entiers signés > complément à 2
Autres exemples d’addition (sur 5 bits) :
5+8:
-5 + 8 :
0 0 1 0 1
[5]
+ 0 1 0 0 0
5 + (-8) :
0 0 1 0 1
[5]
[8]
+ 1 1 0 0 0
[-8]
0 1 1 0 1 [13]
1 1 1 0 1
[-3]
1
1 1 0 1 1 [-5]
1
1 1 0 1 1
[-5]
[-8]
-5 + (-8) :
+ 0 1 0 0 0
[8]
+ 1 1 0 0 0
1 0 0 0 1 1
[3]
1 1 0 0 1 1 [-13]
Représentation consistante : pas de phase d’interprétation
supplémentaire pour les nombres signés
8 = 010002 => -8 = 101112+1 = 110002
© EFREI 2009 - Nicolas Sicard
26
Représentation > Autres codes
Toute information doit être codée par des nombres (entiers ou réels)
ou par des suites de bits. Par exemple, le texte :
Table des codes ASCII :
À chaque caractère est
associé un code entier sur 8
bits (char).
www.cdrummond.qc.ca
© EFREI 2009 - Nicolas Sicard
27
Traitement > Transistors
Transistor CMOS*
Grille
Source
Drain
La tension électrique appliquée à la grille conditionne le
“passage” du courant entre la source et le drain.
*CMOS = Complementary metal oxide semi-conductor
© EFREI 2009 - Nicolas Sicard
28
Traitement > Le transistor
Analogie avec l’interrupteur
ouvert
Source
Drain (D)
0 Volt
2 Volts
Information binaire en un point = potentiel du drain
Interrupteur ouvert : D = 2V = 1
© EFREI 2009 - Nicolas Sicard
29
Traitement > Le transistor
Analogie avec l’interrupteur
fermé
Source
Drain (D)
0 Volt
0 Volts
Information binaire en un point = potentiel du drain
Interrupteur fermé : D = 0V = 0
© EFREI 2009 - Nicolas Sicard
30
Traitement > Le transistor
Transistor N
G (2V)
S
G (0V)
D
S
D
Transistor P
G (2V)
S
G (0V)
D
S
= conduction électrique
D
= isolation électrique
© EFREI 2009 - Nicolas Sicard
31
Transistor > Exemple de l’inverseur
in
S
D
out = NON( in )
© EFREI 2009 - Nicolas Sicard
32
Transistor > Exemple de l’inverseur
in = 0V = 0
S
D
out = 2V = 1
= isolation électrique
© EFREI 2009 - Nicolas Sicard
33
Transistor > Exemple de l’inverseur
in = 2V = 1
S
D
out = 0V = 0
= isolation électrique
© EFREI 2009 - Nicolas Sicard
34
Exemple de l’inverseur > Portes logiques
Porte logique NON :
E
Table de vérité de la porte NON :
E
© EFREI 2009 - Nicolas Sicard
E
E
0
1
1
0
35
Traitement > Portes logiques
NAND (non-et)
NOR (non-ou)
A
B out
A
B out
0
0
1
0
0
1
0
1
1
0
1
0
1
0
1
1
0
0
1
1
0
1
1
0
© EFREI 2009 - Nicolas Sicard
36
Traitement > Portes logiques
XOR (ou exclusif)
AND (et)
A
B out
A
B out
0
0
0
0
0
0
0
1
1
0
1
0
1
0
1
1
0
0
1
1
0
1
1
1
A
B out
0
0
0
0
1
1
1
0
1
1
1
1
OR (ou)
© EFREI 2009 - Nicolas Sicard
37
Traitement > Portes logiques
MUX (multiplexeur)
A
B
S0
S0 out
A
B
S0 out
0
A
0
0
0
0
1
B
0
0
1
0
0
1
0
0
0
1
1
1
1
0
0
1
1
0
1
0
1
1
0
1
1
1
1
1
out
L’entrée A ou B est propagée sur la sortie
suivant la valeur de la commande S0 :
A
B
A
B
0
out = A
1
out = B
© EFREI 2009 - Nicolas Sicard
38
Portes logiques > Exemple de l’additionneur
Problème : additionner 18 et 27 avec des transistors
1
En décimal :
1 8
2 7
4 5
opération logique
1
En binaire :
1
1 0 0 1 0
1 1 0 1 1
1 0 1 1 0 1
© EFREI 2009 - Nicolas Sicard
39
Additionneur > Demi-additionneur 1 bit
Ri+1 opération logique au rang i
1
1 0 0 1 0
1 1 0 1 1
1 0 1 1 0 1
En binaire :
Ai Bi
1
Si=Ai+Bi
Ri+1
0
0
0
0
0
1
1
0
1
0
1
0
1
1
0
1
XOR
AND
A
B
S
Ai
Bi
Si
Ri+1
demi additionneur
© EFREI 2009 - Nicolas Sicard
40
Additionneur > Additionneur 1 bit
Au rang i, il ne faut pas oublier d’ajouter la retenue Ri issue du rang i-1 !
Si = ( Ai + Bi ) + Ri
Il suffit donc de combiner 2 demi-additionneurs :
A
B
1/2
add
S
Ri
Ai
R
Bi
1/2
add
S’i
1/2
add
Si
Ri+1
Ri+1 = ?
© EFREI 2009 - Nicolas Sicard
41
Additionneur > Additionneur 1 bit
Ri
Ri
Ai
Bi
1/2
add
R’i = Ai and Bi
S’i = Ai xor Bi
R”i = S’i and Ri
Si = S’i xor Ri
Ri = R’i or R”i
S’i
R’i
1/2
add
Si
Ai
R”i
+
Bi
Ri+1
Si
Ri+1
additionneur
Ai
0
Bi
0
Ri
0
R’i
0
S’i
0
R”i
0
Si
0
Ri+1
0
0
0
1
0
0
0
1
0
0
1
0
0
1
0
1
0
0
1
1
0
1
1
0
1
1
0
0
0
1
0
1
0
1
0
1
0
1
1
0
1
1
1
0
1
0
0
0
1
1
1
1
1
0
0
1
1
© EFREI 2009 - Nicolas Sicard
42
Portes logiques > Additionneur n bits
n additionneurs 1 bit en étage
R0=0
S0
+
A0
B0
R1
A1
B1
S1
+
R2
A2
B2
1
1
1
0
1
0
0
1
0
1
1
0
1
1
0
1
1
0
1
Ri
Ai
Bi
Si
S2
+
etc
© EFREI 2009 - Nicolas Sicard
43
Stockage > Bascules
Qn = Q avant changement de S et R
Qn+1 = Q après changement de S et R
Bascule RS (principe) :
R
S
Q
Q
S
R
Qn Qn+1
0
0
0
0
0
0
1
1
0
1
X
0
1
0
X
1
1
1
X
X
La dernière valeur de sortie est “mémorisée” tant que S et R sont
à 0. Sinon, la sortie Q vaut S (la combinaison R=S=1 est interdite).
© EFREI 2009 - Nicolas Sicard
44
Stockage > Bascules RS > Exemple
Bascule RS (principe) :
n
S
R
Qn Qn+1
action
S
R
0
1
1
0
0
0
?
1
1
1
enregistrer 1
garde sa valeur
0
0
0
0
0
0
1
1
2
0
1
1
0
enregistrer 0
0
1
X
0
3
0
0
0
0
garde sa valeur
1
0
X
1
4
1
0
0
1
enregistrer 1
1
1
X
X
5
0
0
1
1
garde sa valeur
6
0
0
1
1
garde sa valeur
7
0
1
1
0
enregistrer 0
8
0
0
0
0
garde sa valeur
© EFREI 2009 - Nicolas Sicard
Qn Qn+1
R
Q
S
Q
45
L’information > Récapitulatif
• Information élémentaire est représentée par un bit. L’ordinateur
stocke et manipule des mots (ensemble de bits) de taille fixe.
• Les opérations numériques sont réalisées par des circuits
complexes d’opérations logiques élémentaires (portes logiques)
basées sur l’utilisation de transistors.
• Les informations élémentaires (bits) sont stockées dans des
circuits logiques spécifiques, par exemple des bascules.
© EFREI 2009 - Nicolas Sicard
46
L’unité de traitement (CPU)
© EFREI 2009 - Nicolas Sicard
47
Rappel
Ordinateur = “... exécutant à grande vitesse les
instructions d’un programme enregistré.”
• exécutant : unité de calcul (UAL)
• programme : séquence d’instructions exécutables par la
machine
• instructions : opérations élémentaires (actions) et opérandes
(variables)
• enregistré : mémoire pour stocker les instructions et les données
traitées
© EFREI 2009 - Nicolas Sicard
48
Architecture Harvard
Séparation des instructions et des données dans
des mémoires distinctes
bus
Mémoire
d’instructions
bus
Mémoire de
données
Unité centrale de
traitement (CPU)
© EFREI 2009 - Nicolas Sicard
49
Architecture Harvard
Séparation des instructions et des données dans
des mémoires distinctes
• Avantage : optimisations matérielles (accès mémoires
différenciés)
• Avantage : accès mémoire indépendants (simultanés)
• Inconvénient : saturation de la mémoire (pas de compensation
possible par la seconde)
• Inconvénient : pas de compilation possible sans mécanisme de
transfert de mémoire à mémoire
© EFREI 2009 - Nicolas Sicard
50
Architecture Von Neumann
Instructions et données se partagent la même
mémoire
Unité centrale de
traitement (CPU)
Bus de
données
Mémoire centrale
Bus
d’adresses
© EFREI 2009 - Nicolas Sicard
51
Architecture Von Neumann
Instructions et données se partagent la même
mémoire
• Avantage : une seule technologie => standard => baisse des
coûts
• Avantage : compensation mémoire (moins de problèmes de
saturation)
• Inconvénient : pas d’optimisations matérielles spécifiques
possibles
• Inconvénient : pas d’accès mémoire simultanés
© EFREI 2009 - Nicolas Sicard
52
Schéma synthétique (Von Neumann)
E/S
Unité centrale de
traitement (CPU)
Registres
Unité de
commande
Unité arithmétique
& logique
(UAL)
programme
➁
Mémoire
centrale
(principale)
données
➂
➀
Périphériques
© EFREI 2009 - Nicolas Sicard
53
Mémoire (fonctionnement simplifié)
Mémoire de N mots de n bits :
n bits
Lecture
Écriture
46
0
23
1
87
2
94
3
...
...
17
N-1
Bus d’adresses
adresses
Bus de données
© EFREI 2009 - Nicolas Sicard
54
Registres (processeur de base)
Registre = petite zone mémoire intégrée à la CPU et accessible
“instantanément” par l’UAL et l’unité de commande
‣ PC (Program Counter / Compteur ordinal) : contient l’adresse en
mémoire de la prochaine instruction
‣ IR (Instruction Register) : contient l’instruction à traiter
‣ A0 (Memory Address Register) : indique à la mémoire l’adresse à
laquelle la prochaine instruction de lecture ou d’écriture doit être
effectuée
‣ MBR (Memory Buffer Register) : contient la donnée lue ou à écrire
dans la mémoire
‣ D0 : registre de donnée permettant d’effectuer des opérations
avec l’UAL (accumulateur). Il existe généralement plusieurs
registres de données (D0, D1, D2...)
© EFREI 2009 - Nicolas Sicard
55
Unité de
commande
Unité de commande
Dirige le fonctionnement de tous les autres éléments par des signaux de
commande en utilisant :
le compteur ordinal (PC)
le registre instruction (IR)
le registre de conditions (CCR)
le décodeur : circuit qui détermine l’opération et les opérandes
le séquenceur : circuit ou µ-programme qui active les différents
composants
l’horloge : circuit qui émet des impulsions pour synchroniser tous les
éléments de l’UC
© EFREI 2009 - Nicolas Sicard
56
Unité de commande > Instruction C simple
Instruction = action élémentaire que le processeur est capable de traiter
en une fois + opérandes (càd. les données à traiter)
a = a + b; /* simple instruction du langage C */
1. Décoder l’instruction (quoi faire ?) et les opérandes (avec quoi?)
2. Chercher la valeur de la variable a depuis la mémoire
3. Chercher la valeur de la variable b depuis la mémoire
4. Additionner localement les valeurs reçues
5. Stocker le résultat obtenu en mémoire, à l’emplacement de a
6. Chercher la prochaine instruction à exécuter depuis la mémoire
/* pas si simple pour une machine... */
© EFREI 2009 - Nicolas Sicard
57
Unité de commande > Exécution d’un programme
Dans tous les cas (dans une architecture de type Von Neumann), le
schéma de base est le suivant :
On suppose que les instructions du programme sont logées dans l’ordre
d’exécution à l’adresse 0 de la mémoire. Le comportement de la machine
Von Neumann se décrit alors simplement par :
• PC = 0
• Répeter (indéfiniment)
FETCH : Chercher l’instruction se trouvant à l’adresse PC
DECODE : Décoder l’instruction
EXECUTE : Exécuter l’instruction
PC = PC+1
© EFREI 2009 - Nicolas Sicard
58
Unité de commande > Séquenceur
• Séquenceur : automate distribuant selon un chronogramme
précis les signaux de commande. Deux “écoles” :
‣ câblé : circuit séquentiel complexe avec un sous-circuit pour
chaque instruction (activé par le décodeur)
‣ micro-programmé : on remplace le circuit logique par une ROM
(séquences de micro-instructions)
• Synchronisation des opérations : horloge
‣ cycle machine = durée d’une impulsion d’horloge
‣ cycle CPU = temps d’exécution d’une action élémentaire
front montant
front descendant
© EFREI 2009 - Nicolas Sicard
cycle
59
Séquenceur > CISC
Complex Instruction Set
Les différentes étapes, appelées micro-instructions, sont exécutées dans la
CPU comme un micro-programme. À la compilation, l’instruction C est
traduite par une seule instruction machine de haut niveau.
Avantages : jeu d’instruction de haut niveau, “re-microprogrammation” du
CPU pour de nouvelles instructions.
Inconvénients : jeu d’instructions pléthoriques, fréquences d’horloge faibles
(circuits complexes), micro-programmes = déboguages !
© EFREI 2009 - Nicolas Sicard
60
Séquenceur > RISC
Reduced Instruction Set
Les différentes étapes sont traduites en autant d’instructions machine au
moment de la compilation.
Avantages : jeu d’instructions simple (nombre réduit d’instructions), circuits
plus simples donc fréquences de fonctionnement plus rapides,
optimisations fortes au niveau de la compilation, exploitation du pipeline
d’instructions...
Inconvénients : circuits de commande complexes (combinatoire), ajouts
d’instructions difficiles, compilation plus complexe, besoin de nombreux
registres ...
© EFREI 2009 - Nicolas Sicard
61
Unité Arithmétique et Logique (UAL)
Unité arithmétique &
logique
(UAL)
Circuit logique qui effectue une opération à chaque cycle d’horloge à partir
d’opérandes et d’une commande (opération) fournies en entrée. Le résultat de
l’opération et certains indicateurs (“flags”) sont produits en sortie.
horloge
D1
opérandes
D0/IR
IR
UAL
commande
(opération)
© EFREI 2009 - Nicolas Sicard
résultat
DX
“flags”
CCR
registres
registres
D2
62
UAL > Exemple simple
On considère une UAL capable d’additionner et de complémenter sur 2 bits :
0
B0
B1
A0
A1
+
+
?
R
S0
S1
© EFREI 2009 - Nicolas Sicard
63
UAL > Exemple simple
On considère une UAL capable d’additionner et de complémenter sur 2 bits :
0
B0
B1
+
+
A0
A1
R
MUX
0
1
S0
S1
0
C
Additionner :
0
0
1
0
1
C
A1
A0
B1
B0
© EFREI 2009 - Nicolas Sicard
64
UAL > Exemple simple
On considère une UAL capable d’additionner et de complémenter sur 2 bits :
0
B0
B1
+
+
A0
A1
R
MUX
0
1
S0
S1
1
C
Complémenter :
1
1
0
X
X
C
A1
A0
B1
B0
© EFREI 2009 - Nicolas Sicard
65
Instructions > Différents types
• opérations arithmétiques : additions, soustractions,
multiplications, divisions...
• opérations logiques : et, ou, non, ou-ex etc.
• contrôles de séquence : branchements conditionnels, appels de
procédures...
• transferts de données : de mémoire à registre, de registre à
registre, de registre à mémoire
• entrées / sorties
• opérations diverses : décalages, conversion de format,
permutations, incrémentations...
© EFREI 2009 - Nicolas Sicard
66
Instructions > Codage
Une instruction est une donnée particulière, codée comme une suite de bits
1
0
0
op-code
1
1
1
1
opérande #1
code (valeur entière) de l’opération
à exécuter (addition, chargement
mémoire, test...)
0
0
1
0
1
0
opérande #2
0
1
1
opérande #3
valeurs des opérandes
pour l’opération spécifiée
par l’op-code
Une opérande est le plus souvent une adresse (indice de registre ou
adresse mémoire) ou une valeur immédiate (constante)
© EFREI 2009 - Nicolas Sicard
67
Instructions > Codage
Une instruction est une donnée particulière, codée comme une suite de bits :
1
0
0
1
1
op-code A
1
1
0
0
opérande #1
1
0
opérande #2
1
0
0
1
1
opérande #3
Selon l’op-code, la structure des opérandes (et même la taille de l’instruction)
peut changer :
0
0
1
op-code B
1
1
1
1
0
0
1
0
1 X X X X
opérande #1
© EFREI 2009 - Nicolas Sicard
68
Instructions > Format
• Problème de la taille des instructions
‣ longueurs fixes ou variables
‣ impact sur la mémoire : taille d’un programme proportionnel à la
taille d’une instruction
‣ impact sur les performances : transferts mémoires importants
pour les instructions de grande taille
• Conception du jeu d’instructions influencée par les
connaissances techniques du moment (évolutions possibles)
• Nombre d’opérations (op-codes) sur n bits (n fixé) = 2n
‣ rigidité : nombres d’opérandes différents selon les instructions
© EFREI 2009 - Nicolas Sicard
69
Instructions > Code-opération expansif (16 bits)
0
0
0
0
AD1
AD2
AD3
1
1
1
0
AD1
AD2
AD3
1
1
1
1
0
0
0
0
AD1
AD2
1
1
1
1
1
1
0
1
AD1
AD2
1
1
1
1
1
1
1
0
0
0
0
0
AD
1
1
1
1
1
1
1
1
1
1
1
0
AD
1
1
1
1
1
1
1
1
1
1
1
1
0
0
0
0
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
© EFREI 2009 - Nicolas Sicard
}
15 instructions à 3
adresses
}
14 instructions à 2
adresses (dyadiques)
}
31 instructions à 1
adresse (nonadiques)
}
16 instructions sans
adresse
= 76 instructions 70
Instructions > Assembleur
Langage de programmation “machine” :
L’assembleur propose une syntaxe adaptée au programmeur humain pour
écrire un programme en langage “machine”.
Exemple d’une instruction 68000 (Motorola) :
0 0 1 1
0 0 0 0 0 1
0 0 0 0 0 0
MOVE.W
D1
D0
MOVE.W D1 , D0
transférer la valeur (mot entier) du registre D1 dans le registre D0
© EFREI 2009 - Nicolas Sicard
71
Instructions > Assembleur > Exemple
x = 3*4 + 5;
Compilateur
MOVE.W #3, D0
MULU.W #4, D0
ADD.W #5, D0
MOVE.W D0, x
Assembleur
0011010101011010
0100011010001000
1011111100010101
0010100101000011
© EFREI 2009 - Nicolas Sicard
72
Instructions > Notation RTL
Notation synthétique des transferts de données : Register Transfer Language
M(x) avec x un nombre entier = adresse mémoire x
[R] = contenu du registre nommé R (D0-DN)
[M(x)] = [x] = contenu de la mémoire à l’adresse x
<— = opération d’affectation
© EFREI 2009 - Nicolas Sicard
73
Instructions > Modes d’adressage
Différentes façon d’identifier des opérandes :
• Adressage implicite : le code-op identifie automatiquement
l’opérande, il n’y a pas de champ adresse (opérande). Par
exemple test sur un registre particulier
• Adressage immédiat : la valeur de l’opérande est contenue dans
le champ adresse (si le nombre de bits suffit, sinon dans le mot
suivant l’instruction)
‣ Exemple : MOV #100, R1
( [R1] <— 100 )
• Adressage registre : le champ adresse contient le numéro du
registre opérande
‣ Exemple : CLR R3
( [R3] <— 0 )
© EFREI 2009 - Nicolas Sicard
74
Instructions > Modes d’adressage
• Adressage direct : le champ adresse (ou le mot suivant si le
nombre de bits n’est pas suffisant) contient l’adresse de
l’opérande :
‣ Exemple : MOV 100, R2
( [R2] <— [M(100)] )
• Adressage indirect : le champ adresse contient l’adresse d’un
pointeur (ie. mot en mémoire contenant l’adresse de l’opérande)
‣ Exemple : MOV (R1), R4
( [R4] <— [ M([R1]) ] )
• Adressage indexé : utile pour manipuler les tableaux par
exemple, ce mode permet d’utiliser un registre d’index, auquel
est additionné une adresse de base pour obtenir l’adresse de
l’opérande
‣ Exemple : MOV R4, 100(R3)+
( [ M(100+[R3]) ] <— [R4] )
© EFREI 2009 - Nicolas Sicard
75
Instructions > Modes d’adressage
• Adressage relatif : l’adresse de l’opérande est obtenue en
additionnant le compteur ordinal au contenu du champ
d’adresse
‣ Exemple : instructions de branchement
• Panorama non exhaustif : le 68020 présente près de 50 modes
d’adressage différents !
• Certains modes peuvent ralentir l’exécution des instructions
(calcul des adresses)
© EFREI 2009 - Nicolas Sicard
76
Assembleur > Exemples 68k
▪!
ADDA Addition avec registre d'adresse
Syntaxe: ADDA <AE>, An
Opérande: Mot, Mot long
Addition binaire entre un opérande et le contenu
d'un registre An.
CCR
Non affecté
Exemple: ADDA.W #$1234, A0
ADDA.L -(A1), A0
© EFREI 2009 - Nicolas Sicard
77
Assembleur > Exemples 68k
▪!
ADDI Addition immédiate
Syntaxe: ADDI #<donnée>, <AE>
Opérande: Octet, Mot, Mot long
Addition binaire entre la donnée immédiate et
l'opérande de destination.
CCR
X: Idem à C
N: 1 si résultat<0
Z: 1 si résultat=0
V: 1 si débordement
C: 1 si retenue
Exemple: ADDI.W #$1234, D0
ADDI.B #$03, (A1)+
© EFREI 2009 - Nicolas Sicard
78
Assembleur > Exemples 68k
▪!
CMP Comparaison Registre Dn
Syntaxe: CMP <AE>, Dn
Opérande: Octet, Mot, Mot long
L'Opérande source est soustrait de l'Opérande
destination afin de positionner les flags CCR.
CCR
X: Non affecté
N: 1 si résultat<0
Z: 1 si résultat=0
V: 1 si débordement
C: 1 si retenue
Exemple: CMP.L D0, D1
CMP.W #$1234, D2
CMP.L -(A1), D0
© EFREI 2009 - Nicolas Sicard
79
Instructions
conditionnelles
Instructions
machine
...
SÉQUENCE 0
Programme
Vrai
SÉQUENCE 0
SI (condition vraie) ALORS
{ SÉQUENCE V }
Branchement
CONDITION ?
...
SÉQUENCE V
...
...
SÉQUENCE F
...
SINON
...
SÉQUENCE 1
...
{ SÉQUENCE F }
SÉQUENCE 1
© EFREI 2009 - Nicolas Sicard
Faux
Instructions conditionnelles
Une condition (vrai ou faux) est souvent issue d’une comparaison :
On utilise les opérations arithmétiques (soustraction par exemple)
ou des instructions spécifiques de comparaison.
Le résultat est stocké dans le registre de condition CCR (Condition
Code Register) :
‣ Bit C (Carry) : retenue sortante lors de la dernière opération
‣ Bit V (oVerflow) : dépassement arithmétique de capacité
‣ Bit Z (Zero) : résultat nul lors de la dernière opération
‣ Bit N (Negative) : résultat négatif lors de la dernière opération
Les instructions de branchement conditionnel interprètent l’état du registre
CCR et changent la valeur du compteur ordinal (PC) en fonction
© EFREI 2009 - Nicolas Sicard
81
Instructions conditionnelles > Exemple 68k
Syntaxe, par exemple:
BEQ <étiquette>
Les branchements, ou sauts, sont effectués en fonction du contenu du CCR.
Si la condition est vraie, l'exécution du programme se poursuit à l'adresse
(PC) + déplacement mentionné par l' étiquette.
Exemple:
BEQ $06
BNE LaBas
Description:
CCR
Non affecté
BCC:
BCS:
BEQ:
BNE:
BGE:
BGT:
BHI:
BLE:
BLS:
BLT:
BMI:
BPL:
BVC:
BVS:
BT:
BF:
Branchement si retenue à zéro
Branchement si retenue à un
Branchement si égal
Branchement si différent
Branchement si supérieur ou égal
Branchement si supérieur
Branchement si supérieur
Branchement si inférieur ou égal
Branchement si inférieur ou égal
Branchement si inférieur
Branchement si négatif
Branchement si positif
Branchement si pas de dépassement
Branchement si dépassement
Branchement si vrai
Branchement
si faux
© EFREI 2009 - Nicolas Sicard
Conditions CCR
C=0
C=1
Z=1
Z=0
N xor V = 0
Z + [N xor V] = 0
C + Z = 0
Z + [N xor V] = 1
C + Z = 1
N xor V = 1
N=1
N=0
V=0
V=1
tout le temps
jamais
82
Chemin de données > FETCH
PC
A0
a
+1
Mémoire
(données)
b
IR
OP-CODE
c
d
OPERANDE
MBR
a. [A0] <— [PC]
// adresse de l’instruction à charger sur le bus
b. [PC] <— [PC] + 1
// incrémentation du compteur ordinal
c. [MBR] <— [ M([A0]) ]
// lecture de l’instruction chargée dans le registre MBR
d. [IR] <— [MBS]
// copie de la valeur de MBR dans le registre instruction
© EFREI 2009 - Nicolas Sicard
83
Chemin de données > EXECUTE (ADD P)
PC
A0
+1
Mémoire
(données)
e
f
IR OP-CODE adresse mém. P
MBR
D0
Ajouter à D0 la valeur située en mémoire
à l’adresse P
g
UAL
e. [A0] <— [IR<adresse>]
f. [MBR] <— [ M([A0]) ]
g. [D0] <— [D0] + [MBR]
© EFREI 2009 - Nicolas Sicard
84
Chemin de données > EXECUTE (STORE P)
PC
A0
+1
Mémoire
(données)
i
j
IR OP-CODE
adresse mém.
MBR
h
D0
Mettre la valeur de D0 en mémoire
à l’adresse P
g
UAL
h. [MBR] <— [D0]
i. [A0] <— [ IR<adresse> ]
j. [M([A0])] <— [MBR]
© EFREI 2009 - Nicolas Sicard
85
Chemin de données > EXECUTE (ADD #5)
IR OP-CODE
PC
A0
+1
Mémoire
(données)
opérande=#5
MBR
D0
Valeurs immédiates : ajouter la
constante 5 à D0
k. [D0] <— [D0] + [IR<opérande>]
© EFREI 2009 - Nicolas Sicard
UAL
k
86
Chemin de données > Instructions conditionnelles
PC
A0
+1
Mémoire
(données)
IR OP-CODE
OPÉRANDE
MBR
D0
UAL
Unité de
Commande
Z N V C
© EFREI 2009 - Nicolas Sicard
87
Autres architectures
• Micro-processeur à registres généraux (plus répandu) : la baisse
des coûts de fabrication des composants permet d’inclure
plusieurs registres de donnée (8, 16, 32...), chacun pouvant jouer
le rôle d’accumulateur.
• Microprocesseur à pile : les valeurs en cours de traitement sont
sauvegardées en mémoire dans une pile dont l’adresse de la
tête est sauvegardée dans un registre spécial (SP, Stack Pointer).
Les opérations PUSH et POP permettent respectivement de
ranger ou de retirer une opérande
• Architectures à chargement/rangement : les opérandes sont
obligatoirement des indices de registres ou des valeurs
immédiates (pas d’adresses mémoire). Les opérations LOAD et
STORE permettent respectivement de charger des registres
depuis la mémoire et vers la mémoire.
© EFREI 2009 - Nicolas Sicard
88
Processeur mono-cycle
• Principe : traitement d’une instruction en un seul cycle d’horloge
‣ FETCH + DECODE + EXECUTE en un cycle !
‣ toutes les instructions doivent suivre à peu près le même
chemin
• UNE instruction = UN ensemble de signaux de contrôle
‣ adapté aux architectures RISC
• Séquenceur réalisé par un circuit logique de décodage
© EFREI 2009 - Nicolas Sicard
89
Processeur mono-cycle > MIPS simplifié
• “Microprocessor without Interlocked Pipeline Stages”
‣ MIPS Technologies (80’)
‣ mise en œuvre de la technologie pipeline d’instructions
• Architecture à chargement / rangement
‣ 32 registres généraux (r0 à r31)
‣ instructions codées sur 32 bits (taille fixe)
‣ mémoire adressable par octets => instructions placées à des
adresses mémoire multiples de 4
© EFREI 2009 - Nicolas Sicard
90
MIPS > Jeu d’instructions
• Instructions de type R (Registre) : ne travaillent qu’avec les
registres (opérations arithmétiques et logiques)
31
26 25
opcode
21 20
rs
16 15
rt
11 10
rd
6
5
0
code UAL
‣ opcode = code de l’opération
‣ rs = registre source (5 bits), en lecture, fournit une valeur
‣ rt = registre transit (5 bits), en lecture ou écriture, selon l’opcode
‣ rd = registre destination (5 bits), en écriture (reçoit le résultat)
‣ bits 6 à 10 non utilisés
‣ code UAL = nature de l’opération arithmétique ou logique
© EFREI 2009 - Nicolas Sicard
91
MIPS > Jeu d’instructions
• Instructions de type I (Immédiat) : une des opérandes de type
immédiat
31
26 25
opcode
21 20
rs
16 15
rt
0
valeur immédiate
‣ opcode = code de l’opération
‣ rs = registre source (5 bits), en lecture, fournit une valeur
‣ rt = registre transit (5 bits), en lecture ou écriture, selon l’opcode
‣ bits 0 à 15 : une valeur entière ou une adresse mémoire (load/
store)
© EFREI 2009 - Nicolas Sicard
92
MIPS > Phase FETCH
Remarque : les signaux de contrôle ne sont pas générés (ils le sont à la phase
DECODE)
PC
adresse
instruction
Mémoire
(instructions)
© EFREI 2009 - Nicolas Sicard
93
MIPS > Phase DECODE
31
Type R :
26 25
21 20
rs
opcode
16 15
rt
11 10
6
5
rd
0
code UAL
15
Type I :
valeur immédiate
31-26
Séquenceur
25-21
instruction
32 bits
0
‣ Distinction simultanée des
types d’instructions R et I en
anticipation du décodage
rs
rt
20-16
banc de
registres
15-11
‣ Le code UAL est dirigé vers le
dispositif de contrôle de l’UAL
noté C
rd
valeurs
immédiates
15-0
5-0
C
© EFREI 2009 - Nicolas Sicard
94
MIPS > Phase EXECUTE
Selon l’instruction, rt ou rd en destination : multiplexeur à l’entrée du banc de
registres, commandé par le séquenceur (via le signal REG dest)
Séquenceur
REG dest
rd codé sur 5 bit
valeur immédiate
sur 16 bits
rs
rt
20-16
15-11
1 0
rs codé sur 5 bit
rt codé sur 5 bit
REG write
25-21
rd
15-0
32 bits
[rs]
[rt]
X
32 bits
‣ Pour une instruction I, le signal
REG write indique si une
donnée doit être écrite ou non
dans le registre destination
(LOAD : REG write = 1,
STORE : REG write = 0)
32 bits
32 bits
donnée
à écrire
© EFREI 2009 - Nicolas Sicard
‣ Extension (X) de la valeur
immédiate de 16 à 32 bits
avant calcul (attention au signe)
95
Phase EXECUTE > Gestion de l’UAL
Deux signaux déterminent le comportement de l’UAL :
‣ UAL op indique si une opération arithmétique ou logique a lieu (1) ou s’il
s’agit d’une simple recopie de l’entrée vers la sortie (0)
‣ UAL src permet de choisir la seconde opérande entre [rt] (0) et la valeur
immédiate étendue à 32 bits (1)
CCR
UAL src
opération
(codeUAL) sur
les valeurs des
registres rs et rt
la valeur
opération
UAL src
immédiate
(codeUAL) sur
=
est propagée les valeurs de rs
1
en sortie
et valeur imm.
[rs]
[rt]
valeur
immédiate
code UAL
UAL op
© EFREI 2009 - Nicolas Sicard
flags
32 bits
32 bits
32 bits
donnée à
écrire
32 bits
5-0
UAL
la valeur du
UAL src
registre rt est
=
propagée en
0
sortie
UAL op = 1
1 0
UAL op = 0
C
96
Phase EXECUTE > Accès mémoire
Attention : seules les instructions LOAD et STORE impliquent la mémoire
Signaux de contrôle :
‣ MEM read / MEM write indiquent si la donnée doit être lue ou écrite
‣ MEM—>REG permet de choisir entre la sortie de la mémoire ou la sortie de
l’UAL. Signal à 0 quand l’instruction n’est pas LOAD/STORE
MEM—>REG
LOAD
1
Mwrite
0
M->R
MEM
read
0
MEM
write
donnée
STORE
0
1
x
sortie de
l’UAL
AUTRE
0
0
1
[rt]
donnée lue
adresse
Mémoire
(données)
32 bits
donnée à
écrire
© EFREI 2009 - Nicolas Sicard
0 1
Mread
97
Phase EXECUTE > Instructions de branchement
Adresses mémoire des instructions multiples de 4
‣ passer d’une instruction à une autre : [PC] <— [PC] + 4
1 0
‣ Exemple : BEQ <deplacement> : [PC] <— [PC] + 4 + <deplacement> si Z=1
( seulement +4 si Z=0 )
+
+
4
<<2
PC
adresse
Mémoire
(instructions)
ET
32 bits
déplacement
© EFREI 2009 - Nicolas Sicard
CCR<Z>
branchement
98
0
Processeur mono-cycle > Schéma synthétique
instruction
Mémoire
(instructions)
15-11
MEM—>REG
REG write
rs
rt
rd
Z
[rs]
[rt]
donnée
15-0
MEM
read
1
UAL src
MEM
write
donnée lue
0
20-16
1 0
adresse
25-21
ET
UAL
REG dest
branchement
0
PC
D
Mémoire
(données)
1
31-26
C
o
n
t
r
ô
l
e
+
+
1
4
donnée à
écrire
X
5-0
C
© EFREI 2009 - Nicolas Sicard
UAL op
99
Pipeline (traitement entrelacé des instructions)
• Processeur mono-cycle n’est possible qu’avec des circuits très
simples : la complexification des circuits conduit à une
augmentation du temps de traversée du signal, à une diminution
de la fréquence d’horloge donc des performances
• Idée : associer chaque phase (FETCH/EXEC/DECODE) à une
unité fonctionnelle d’un cycle => micro-programmes.
Conséquences : diminution du temps de cycle mais plus d’un
cycle par instruction
• Meilleure idée : faire “travailler” les unités fonctionnelles en
parallèle sur des instructions différentes ! On crée un pipeline
d’instructions
© EFREI 2009 - Nicolas Sicard
100
Pipeline > Déroulement d’une instruction
unités
fonctionnelles
FETCH
instruction
i
instruction
i
DECODE
instruction
i
EXECUTE
1
2
© EFREI 2009 - Nicolas Sicard
3
cycles
d’horloge
101
Pipeline > Déroulement de plusieurs instructions
unités
fonctionnelles
FETCH
i
i+1
i
DECODE
i+2
i+1
i
EXECUTE
1
2
3
i+2
i+1
4
5
© EFREI 2009 - Nicolas Sicard
6
i+2
7
8
9
cycles
d’horloge
102
Pipeline > Déroulement de plusieurs instructions
unités
fonctionnelles
‣ Temps de traitement d’une
instruction inchangé (3 cycles)
FETCH
i
i+1 i+2
i
DECODE
i+1 i+2
i
EXECUTE
1
2
‣ Mais le débit global de
traitement d’une séquence
d’instructions a triplé (1 instr.
par cycle au lieu d’une instr.
tous les 3 cycles)
3
i+1 i+2
4
5
© EFREI 2009 - Nicolas Sicard
6
7
8
9
cycles
d’horloge
103
Pipeline > Exemple du MIPS
©Wikipedia
© EFREI 2009 - Nicolas Sicard
104
Pipeline > Limitations
Problème des branchements :
‣ branchement pris : l’instruction suivante n’est pas i+1, il faut stopper le
pipeline le temps de calculer la nouvelle adresse et de charger l’instruction
FETCH
i
beq
i
DECODE
EXECUTE
1
2
i+D
beq
i+D
i
beq
3
4
i+D
5
6
7
‣ dépendances de données entre instructions, ex : a = b+c puis d = 3*a;
‣ cas de l’exécution d’une boucle simple : un branchement à chaque itération
➡ systèmes de prédiction de branchement (statistiques) pour optimiser
© EFREI 2009 - Nicolas Sicard
105
Pipeline > Profondeur
La profondeur d’un pipeline est le nombre d’étages (ie. le nombre
d’unités fonctionnelles).
Plus le nombre d’étages est grand, plus les circuits sont courts,
plus la fréquence d’exécution est élevée.
Exemples :
‣ Intel Pentium 4E “Prescott” (architecture NetBurst 2004) : le
pipeline pour le calcul d’entiers passe à 31 étages !
‣ par comparaison le Motorola PowerPC G4 présente 7 étages
Besoin d’unités de prédiction de branchement très efficaces :
thèmes de recherche populaires au début des années 2000.
© EFREI 2009 - Nicolas Sicard
106
Architectures super-scalaires
On duplique les unités fonctionnelles pour traiter deux instructions en parallèle
‣ Temps de traitement d’une
instruction inchangé (3 cycles)
unités
fonctionnelles
FETCH (1)
FETCH (2)
DECODE (1)
DECODE (2)
EXECUTE (1)
EXECUTE (2)
i i+2 i+4
i+1 i+3 i+5
i i+2
i+1 i+3
i
i+1
1
2
3
i+4
i+5
i+2 i+4
i+3 i+5
4
5
© EFREI 2009 - Nicolas Sicard
‣ Mais le débit global de
traitement d’une séquence
d’instructions a idéalement
sextuplé (2 instr. par cycle au
lieu d’une instr. tous les 3
cycles)
6
7
8
9
cycles
d’horloge
107
Autres architectures
VLIW :
‣ l’instruction (256 bits) contient les opérations pour chaque unité de calcul
disponible
‣ nécessite d’importantes modifications des technologies de compilation
Architectures vectorielles :
‣ une seul instruction appliquée à plusieurs données simultanément
‣ s’applique uniquement à des problèmes adaptés (traitement image...)
‣ registres de grande taille (coûteux)
‣ mise en œuvre sous la forme d’unités particulières dans les processeurs
génériques (Intel MMX/SSE - Motorola Altivec)
© EFREI 2009 - Nicolas Sicard
108
Tendances > Architectures multi-cœurs
Idée : prendre en compte le parallélisme “grossier” du fonctionnement d’un
ordinateur (plusieurs processus en cours d’exécution)
‣ on duplique des CPU complètes sur un même circuit intégré
‣ partage de la mémoire (et mémoire cache) : problèmes de maintien de la
cohérence des données entre unités de traitement
‣ nécessite une adaptation des systèmes d’exploitation et des programmes
(multi-threading) : Grand Central (Apple), Threading Building Blocks (Intel)
Exemples :
‣ Intel Core 2 Duo : architecture dual-core (deux CPU)
‣ AMD dual Opteron (2005)
‣ IBM PowerPC 970MP
© EFREI 2009 - Nicolas Sicard
109
Tendances > Co-processeurs graphiques
GPGPU : General Purpose computing on Graphics Processing Units
‣ tirer parti de la puissance de calcul graphique et mémoire des cartes et
chipsets vidéo actuels
‣ on déporte les calculs fortement SIMD vers la carte graphique
‣ on récupère le résultat dans la mémoire centrale
‣ nécessite une standardisation des langages et API d’accès aux GPU
Exemples :
‣ CUDA (Nvidia)
‣ OpenCL (Open Computer Library)
© EFREI 2009 - Nicolas Sicard
110
UAL > Récapitulatif
L’unité de commande (séquenceur) orchestre les échanges entre
la mémoire, l’unité de calcul (UAL) et les registres à chaque cycle
d’horloge, en fonction des instructions du programme
Les instructions sont des mots mémoire contenant un code
opération (op-code) et des opérandes (valeurs, adresses mémoire
ou de registre)
Les branchements conditionnels sont assurés par des instructions
spécifiques qui modifient le registre PC en fonction de l’état du
registre de condition (CCR)
L’utilisation du pipeline d’instructions permet d’optimiser
l’utilisation des unités de calcul et de mouvements mémoire et
d’augmenter le débit de traitement
© EFREI 2009 - Nicolas Sicard
111
La hiérarchie mémoire
© EFREI 2009 - Nicolas Sicard
112
La hiérarchie mémoire
Organisation
Adressage
Mémoire cache
© EFREI 2009 - Nicolas Sicard
113
La mémoire > Organisation
Mémoire de 2N mots de M bits :
M bits
R
W
‣ N : largeur du bus d’adresse
46
0
23
1
87
2
94
3
...
...
‣ M : largeur du bus de données
Bus
d’adresses
‣ 8 : coefficient bits/octet
Capacité C de la mémoire en
octets :
17
Bus
de
données
2N-1
adresses
2N M
C=
8
114
© EFREI 2009 - Nicolas Sicard
La mémoire > Organisation
Mémoire de 2N mots de M bits :
M bits
R
W
Pour C = 256 Mo :
46
0
23
1
87
2
94
3
...
...
M
Bus
d’adresses
N
8 bits 28 bits
C (octets)
(228 x 8) / 8
32 bits 26 bits (226 x 32) / 8
64 bits 25 bits (225 x 64) / 8
17
Bus
de
données
Quelle est la meilleure réparition ?
2N-1
adresses
115
© EFREI 2009 - Nicolas Sicard
La mémoire > Critères d’organisation
• nombre de pistes : nombre minimal pour N maximal
• différences entre les tailles des données traitées par la CPU et
les applications (8, 16, 32 ou 64 bits ?)
• privilégier les performances de débit (quantité de données
chargées en un échange) :
‣ augmenter la taille de la cellule mémoire
‣ augmenter la largeur du bus de données
‣ réduire la largeur du bus d’adresses
© EFREI 2009 - Nicolas Sicard
116
Organisation > Traitement des octets
Augmenter les performances de débit implique une augmentation
de la largeur du bus de données (32 ou 64 bits). Par ailleurs, l’unité
naturelle de traitement des processeurs tend vers 32 ou 64 bits.
Mais historiquement beaucoup de données sont encore codées
sur des mots de 8 bits (typage du langage C, fichiers texte...) :
l’incrément d’adresse est le plus souvent de 1 octet.
Problème : comment traiter un mot (32 bits) ou un demi-mot (16
bits) pour l’adressage et le stockage “calé” sur 8 bits ?
2 écoles : petit boutisme (little endian) et grand boutisme (big
endian)
© EFREI 2009 - Nicolas Sicard
117
Traitement des octets > Endianness
Ordre de rangement des octets à l’intérieur d’un mot de 32 bits en
mémoire d’incrément d’adresse d’un octet
Ex : 0x554E4958
Gros boutisme (big endian) :
32 bits
@
0
1
2
3
#
55
4E
49
58
α
U
N
I
X
32 bits
Petit boutisme (little endian) :
@
0
1
2
3
#
58
49
4E
55
α
X
I
N
U
© EFREI 2009 - Nicolas Sicard
118
Traitement des octets > Endianness
Ordre de rangement d’un octet à l’intérieur d’un mot de 32 bits en
mémoire d’incrément d’adresse d’un octet
Ex : 0x01
32 bits
Gros boutisme (big endian) :
@
0
1
2
3
#
.00
.00
.00
.01
32 bits
Petit boutisme (little endian) :
@
0
1
2
3
#
.01
.00
.00
.00
© EFREI 2009 - Nicolas Sicard
119
Traitement des octets > Big Endian
Ordre de rangement des octets à l’intérieur d’un mot de 32 bits
dans l’ordre mots de “poids fort en tête”
Ex : 0x01
32 bits
Gros boutisme (big endian) :
@
0
1
2
3
#
.00
.00
.00
.01
Exemples : Motorola 68000, SPARC (Sun Microsystem)
Avantage : dans l’ordre naturel de lecture d’un nombre
© EFREI 2009 - Nicolas Sicard
120
Traitement des octets > Little Endian
Ordre de rangement des octets à l’intérieur d’un mot de 32 bits
dans l’ordre mots de “poids faible en tête”
Ex : 0x01
32 bits
Petit boutisme (little endian) :
@
0
1
2
3
#
.01
.00
.00
.00
Exemples : Famille Intel x86
Avantage : accès direct aux petites valeurs en 8 ou 16 bits (il suffit
de tronquer après le 1er ou le 2nd octet).
© EFREI 2009 - Nicolas Sicard
121
Endianness > Exemple (Little Endian)
int
char
char
long
short
i=0;
*pval8;
str[]="UNIX";
val32;
val16;
Sortie standard
int main()
{
unsigned
unsigned
unsigned
unsigned
unsigned
val32 = 0x554E4958;
val16 = 0xABCD;
Programme
printf("Stockage d'une val 16 bits\n");
printf("val16 = %#X @%#x\n", val16, &val16);
pval8 = (unsigned char*)(&val16);
for(i = 0; i < 4; i++)
printf("val8[%d] = %#02X\n",i, pval8[i]);
@0xbffffa7a
printf("Stockage d'une char*\n");
printf("val8 = %s @%#x\n", str, str);
pval8 = str;
for(i = 0; i < 4; i++)
printf("%c",pval8[i]);
return 0;
}
@0xbffffa7b
val16
@0xbffffa7c
@0xbffffa7d
@0xbffffa7e
Mémoire
printf("Stockage d'une val 32 bits\n");
printf("val32 = %#X @%#x\n", val32, &val32);
pval8 = (unsigned char*)(&val32);
for(i = 0; i < 4; i++)
printf("val8[%d] = %#02X\n",i, pval8[i]);
for(i = 0; i < 4; i++)
printf("%c",pval8[i]);
Stockage d'une val 16 bits
val16 = 0xABCD @0xbffffa7a
val8[0] = 0xCD
val8[1] = 0xAB
val8[2] = 0x58
val8[3] = 0x49
Stockage d'une val 32 bits
val32 = 0x554E4958 @0xbffffa7c
val8[0] = 0x58
val8[1] = 0x49
val8[2] = 0x4E
val8[3] = 0x55
XINU
Stockage d'une char*
val8 = UNIX @0xbffffa83
UNIX
@0xbffffa81
val32
0x49 (‘I’)
0x4E (‘N’)
0x55 (‘U’)
Non utilisé
(Alignement)
@0xbffffa82
@0xbffffa83
‘U’
@0xbffffa84
‘N’
@0xbffffa85
© EFREI 2009 - Nicolas Sicard
0xAB
0x58 (‘X’)
@0xbffffa7f
@0xbffffa80
0xCD
str
‘I’
@0xbffffa86
‘X’
@0xbffffa87
‘\0’
122
Traitement des octets > Bilan
Problème : stockage cohérent dans une même machine mais pas
entre architectures différentes (sauf si les données sont codées
comme une suite d’octets (ex: ASCII) ).
Transmission des mots mémoire (>8 bits) : nécessité de connaître
l’ordre de chaque machine connectée ?!
Protocole IP (Internet) : impose le standard Network byte order (=
big endian) pour tous les paquets transmis, quel que soit
l’endianness naturel de la machine.
Remarque : beaucoup d’architectures acceptent les deux modes
(PowerPC, ARM, MIPS, IA-64...)
© EFREI 2009 - Nicolas Sicard
123
Organisation > Hiérarchie mémoire
temps de
réponse
coût à
l’octet
~100 octets
registres
1 à 8 Go
4 à 50 Go
100 Go à 1To
1 To à 10 To
~ 100 To
RAM
disques optiques
volatile
persistante
disques durs
bandes magnétiques (DAT, DLT...)
systèmes d’archivage (robots...)
taille
© EFREI 2009 - Nicolas Sicard
124
Organisation > Mémoires RAM
RAM : Random Access Memory (accès non séquentiel)
SRAM : Static RAM (à base de bascules, pas de rafraichissement
nécessaire, alimentation électrique continue, coûteux)
DRAM : Dynamic RAM (à base de transistors, rafraichissements
réguliers, haute densité, bon marché)
FPM RAM : Fast Page Mode RAM (lecture par blocs)
EDO RAM : Extended Data Out RAM (moins de rafraîchissements)
SDRAM : Synchronous DRAM (synchronisé au bus de la CPU,
accès entrelacés)
DDR(1,2,3) SDRAM : Dual Data Rate SDRAM (débit double)
© EFREI 2009 - Nicolas Sicard
125
Organisation > RAM vs. CPU
Remarque : un processeur à 2Ghz est capable de traiter plus
d’une donnée toutes les 0,5ns, une RAM rapide a une latence de
l’ordre de 5 à 10ns...
Question : comment accélérer les transferts ?
‣utiliser au maximum les registres (mais taille limitée et
problème de compilation)
‣augmenter le débit (une des améliorations de l’architecture)
‣réduire la distance entre la RAM et la CPU ?....
© EFREI 2009 - Nicolas Sicard
126
RAM vs. CPU > Distance
Question : quelle distance L est parcourue par un signal en 0,5ns ?
‣au plus rapide (vitesse de la lumière) c = 3.108 ms-1
‣T = 0,5ns = 5.10-10s
‣L = c.T = 0,15m !
Idéal : intégration de la mémoire au support du processeur
Problème : intégration trop coûteuse, peu flexible (augmentation de
la mémoire)
Solution : mémoire intermédiaire en taille et en rapidité entre la
mémoire centrale et la CPU.
© EFREI 2009 - Nicolas Sicard
127
Organisation > Mémoire cache
Mémoire de taille réduite (de 32Ko à 4Mo selon la proximité) qui
contient une copie de fragments de la mémoire centrale
Le temps d’accès au cache tc est très inférieur au temps d’accès
de la mémoire tm.
RAM
tc
CACHE
CPU
tm >> tc
© EFREI 2009 - Nicolas Sicard
128
Mémoire cache > Principe
Le cache donne l’illusion d’une mémoire très rapide de grande
capacité. Pour obtenir une donnée, la CPU va transmettre son
adresse au cache.
‣si le cache possède la donnée correspondante, il la
transmet au CPU (rapide)
SUCCES = CACHE HIT
‣sinon, la donnée est en mémoire, il faut la faire transiter
depuis la RAM (lent)
ECHEC = CACHE MISS
© EFREI 2009 - Nicolas Sicard
129
Mémoire cache > Performances
Soit tglob le temps moyen d’accès à une donnée, tc le temps
d’accès via le cache et tm le temps d’accès via la mémoire. Soit h
(0 ≤ h ≤ 1) le taux de HIT.
On fait un accès au cache (tc) à chaque requête mémoire :
‣s’il y a HIT, alors on n’accède pas à la mémoire
‣sinon, on doit accéder à la mémoire en un temps tm avec
un taux de 1-h
d’où un temps d’accès moyen :
tglob = tc + (1-h)tm
© EFREI 2009 - Nicolas Sicard
130
Performances > Application numérique
Soit Cc=1Go la capacité du cache et Cm=1Mo la capacité de la
RAM. Soit tc = 8ns et tm = 40ns.
Hypothèse : le cache contient des données sélectionnées
aléatoirement, donc h = Cc/Cm = 1/1024 = 2-10 << 1.
Alors :
tglob = tc + (1-h)tm ≈ tc + tm = 48ns > tm !!
Conclusion : on doit optimiser le choix des données stockées en
cache pour maximiser le nombre de HIT. Il faut anticiper les accès.
Questions : Comment optimiser le contenu de la mémoire cache
pour augmenter le taux de succès ? Quelles données copier en
cache ? Comment faire quand le cache est plein ?
© EFREI 2009 - Nicolas Sicard
131
Performances > Principe de localité temporelle
Lorsqu’un programme accède à une certaine adresse, il est
probable qu’il y accède de nouveau peu de temps après.
Exemples : les programmes sont souvent construits à base de
boucles, d’où une réutilisation fréquente de certaines valeurs
(compteurs...)
Conséquence : lors de la mise à jour d’une valeur dans le cache (à
cause d’un miss), on a intérêt à éliminer les données les plus
anciennes d’abord.
Méthode FIFO (First In First Out) empile les accès
Méthode LRU (Least Recently Used) compte le nombre d’accès
depuis la dernière lecture/écriture pour chaque emplacement
© EFREI 2009 - Nicolas Sicard
132
Performances > Principe de localité spaciale
Quand un programme accède à une donnée à une certaine
adresse, il est probable qu’il accède à des données aux adresses
proches de celle-ci.
Exemples : un programme lui-même est une séquence
d’instructions contigües en mémoire, programmes de manipulation
de texte (séquence de caractères), d’images, de son...
Conséquence : lors de la mise à jour d’une valeur dans le cache (à
cause d’un miss), on a intérêt à transférer un bloc de valeurs
localement proches en mémoire. On parle alors de lignes de
cache.
© EFREI 2009 - Nicolas Sicard
133
Evolution du cache > Cas d’une lecture
Au départ, on considère que la mémoire cache est vide.
Si la CPU veut accéder à une donnée, elle présente son adresse à
la mémoire cache. Deux cas possibles :
‣ la donnée n’est pas disponible en cache (MISS) :
1. la ligne de cache correspondante est cherchée en RAM
2. elle est recopiée dans le cache, éventuellement en
remplacement d’une autre ligne de cache (LRU)
‣ la donnée est présente en cache (HIT) : elle est transmise à
la CPU. Le cache n’est pas mise à jour mais la date
d’accès à la ligne de cache est rafraîchie
© EFREI 2009 - Nicolas Sicard
134
Evolution du cache > Cas d’une écriture
La CPU veut enregistrer une donnée, il fournit sa valeur et son
adresse. Ecriture en cache ? Ou en RAM ? En cache et en RAM ?
Important : préserver la cohérence des données entre RAM et
cache. La RAM est la référence : la donnée est écrite en RAM.
Comportement du cache :
‣ écriture de la valeur surtout si la données y est déjà
présente
‣ le plus simple est d’invalider la donnée en cache si elle s’y
trouve (pas de mise à jour nécessaire, il suffit d’activer un
bit d’invalidation)
© EFREI 2009 - Nicolas Sicard
135
Mémoire cache > Implémentation
Question : quelles implémentations pour ce type de mémoire dans
un circuit ?
Il en existe deux grandes familles :
‣ les caches associatifs : chaque emplacement du cache
contient un couple (adresse / valeur)
‣ les caches à correspondance directe : à un emplacement
donné du cache ne correspond qu’un ensemble restreint
d’adresses
Les solutions retenues et implémentées réellement sont bien
souvent un compromis entre les deux !
© EFREI 2009 - Nicolas Sicard
136
Implémentation > Cache Associatif
Comparable à un tableau indexé :
v
v
v
adresse
adresse
adresse
Cache de 2N
emplacements
donnée(s)
donnée(s)
donnée(s)
1 emplacement
de cache
...
v
v
adresse
adresse
bits d’invalidation
donnée(s)
donnée(s)
lignes de cache
© EFREI 2009 - Nicolas Sicard
137
Cache Associatif > Lecture
lecture @0x10
CPU
bus d’@
cache initialement vide
0
0
@0x00
@0x00
????????
????????
0
@0x00
????????
On cherche l’adresse
0x10 dans le cache,
ligne par ligne.
Si elle n’est pas
présente dans le cache,
il y a échec (MISS)...
...
0
@0x00
????????
0
@0x00
????????
MISS
© EFREI 2009 - Nicolas Sicard
138
Cache Associatif > Màj. après MISS
lecture @0x10
CPU
bus d’@
cache initialement vide
1
0
@0x10
@0x00
????
0
@0x00
????
... la donnée est alors
transmise depuis la
RAM vers le cache et la
CPU
...
0
@0x00
????
0
@0x00
????
0xABCD
bus de données
© EFREI 2009 - Nicolas Sicard
RAM
139
Cache Associatif > Lecture (II)
lecture @0x10
CPU
bus d’@
1
0
@0x10
@0x00
0xABCD
????
0
@0x00
????
Si la donnée est
présente et valide, elle
est rapatriée directement
depuis le cache.
...
0
@0x00
????
0
@0x00
????
bus de données
HIT
© EFREI 2009 - Nicolas Sicard
RAM
140
Cache Associatif > Lecture (III)
lecture @0x4A
CPU
bus d’@
Si la donnée est
présente mais invalide,
elle est transmise depuis
la RAM vers le cache et
la CPU
bus de données
1
1
@0x10
@0x86
0xABCD
0x875D
0
@0x00
????
...
1
0
@0x4A
0xE65F
1
@0x25
0x0000
MISS
© EFREI 2009 - Nicolas Sicard
0x4321
RAM
141
Cache Associatif > Lecture (MISS + cache plein)
lecture @0x31
CPU
bus d’@
âge de
l’emplacement
1
1
@0x10
@0x86
0xABCD
0x875D
0
3
1
@0x12
0x6234
2
Si la donnée n’est pas
présente et que le cache
est plein...
...
1
@0x4A
0xE65F
8
1
@0x25
0x0000
5
MISS
© EFREI 2009 - Nicolas Sicard
142
Cache Associatif > Lecture (LRU)
lecture @0x31
CPU
bus d’@
“âge” de
l’emplacement
1
1
@0x10
@0x86
0xABCD
0x875D
1
4
1
@0x12
0x6234
3
Si la donnée n’est pas
présente et que le cache
est plein...
... il faut remplacer la
ligne la plus “âgée” par
les nouvelles données
provenant de la RAM.
...
1
@0x31
1
@0x25
0
0x0000
0x4321
bus de données
© EFREI 2009 - Nicolas Sicard
6
RAM
143
Cache Associatif > Ecriture
Deux politiques principales :
‣ write-through : chaque écriture dans le cache est
immédiatement répercutée dans la RAM
‣ write-back : une ligne de cache n’est écrite en mémoire
que lorsqu’elle est libérée. Dans ce cas, un bit particulier
(dirty bit) indique si les données ont été modifiées ou non
en cache. Si oui, l’écriture est effectuée, sinon la ligne est
simplement libérée
Politiques intermédiaires :
‣ write-through : écritures stockées dans une file d’attente
‣ write-back : écritures pendant les périodes sans échange
avec la mémoire
© EFREI 2009 - Nicolas Sicard
144
Implémentation > Cache à correspondance directe
Défauts des caches associatifs :
‣ stockage de l’adresse entière (pour chaque ligne de cache)
‣ les adresses ne sont pas classées : la recherche dans le
tableau associatif est très complexe en circuits donc longue et
coûteuse
Solution : ne faire correspondre qu’un seul emplacement du
cache à une adresse mémoire donnée.
Inversement, à un emplacement donné peuvent correspondre
plusieurs adresses.
Technique : une partie de l’adresse (codée sur p bits) code le
numéro de l’emplacement correspondant
© EFREI 2009 - Nicolas Sicard
145
Cache à correspondance directe > Adresse
adresse mémoire (p bits)
tag
index
offset
p-q-r bits
q bits
r bits
“étiquette” de la ligne
de cache stockée
à l’indice index
indice du mot mémoire
dans la ligne de cache
contenant 2r mots
indice de la ligne dans le
cache contenant 2q lignes
Toutes les adresses de même index se partagent la même ligne de cache
© EFREI 2009 - Nicolas Sicard
146
Cache à correspondance directe > Exemple
adresse mémoire (32 bits)
tag
index (8 bits)
offset (4 bits)
980A0
B2
A
index
tag
data (16 octets)
0
1
2
3
4
5
6
7
8
9
A
B
C
D
E
F
0x01
0x02
0x03
...
0xB1
0xB2 980A0
0xB3
...
Cache de 28 (256)
emplacements
de 16 octets
0xFD
0xFE
0xFF
© EFREI 2009 - Nicolas Sicard
147
Cache à correspondance directe > Lecture
adresse mémoire (32 bits)
tag
index (8 bits)
offset (4 bits)
980A0
B2
A
index
tag
data (16 octets)
0
1
2
3
4
5
6
7
8
9
A
B
C
D
E
F
0x01
0x02
0x03
...
0xB1
0xB2 980A0
0xB3
...
=
MUX
HIT/MISS
bus de données
© EFREI 2009 - Nicolas Sicard
148
Cache à correspondance directe > Bilan
Avantages :
‣ stockage d’une partie de l’adresse seulement (tag)
‣ accès direct à l’emplacement de la ligne de cache
Inconvénients :
‣ un seul emplacement possible pour une adresse => conflits
‣ effets “ping-pong” lors d’accès mémoire alternés à partir
d’adresses de même index (màj. du cache à chaque accès)
Objectifs : profiter des avantages des deux types de cache...
© EFREI 2009 - Nicolas Sicard
149
Caches associatifs par 2/4/8 > Exemple
adresse mémoire (32 bits)
tag
index (8 bits)
offset (4 bits)
980A0
B2
A
4 x caches de 256
emplacements de
16 octets
2, 4 ou 8 emplacements possibles pour
chaque index
index
tag
data (16 octets)
index
tag
data (16 octets)
index
tag
data (16 octets)
8 octets)
9 A B C D E F
index
tag00 11 22 33 44 55 66 7data
7 (16
8
9 A B C D E F
0 1 2 3 4 5 6 7 8
9 A B C D E F
0x01
0 1 2 3 4 5 6 7 8
9 A B C D E F
0x01
0x01
0x02 0x01
0x02
0x02
0x03 0x02
0x03
0x03
...
0x03
...
...
0xB1
...
0xB1
0xB1
0xB20xB1
980A0
0xB2 980A0
0xB2 980A0
0xB30xB2 980A0
?
0xB3
0xB3
...
0xB3
...
...
0xFD
...
0xFD
0xFD
0xFE 0xFD
0xFE
0xFE
0xFF 0xFE
0xFF
0xFF
0xFF
© EFREI 2009 - Nicolas Sicard
150
Niveaux de caches
Objectifs : trouver le meilleur compromis possible coût/
performances.
Contraintes : plus une mémoire est rapide, plus elle est chère
Techniques : ajouter des niveaux de cache
‣ L1 (interne) : intégré à la CPU, petite capacité (32/64Ko), très
rapide, séparation des instructions et des données
‣ L2 (externe) : capacité moyenne (512Ko/2Mo), éloigné de la
puce
© EFREI 2009 - Nicolas Sicard
151
Téléchargement
Random flashcards
Commune de paris

0 Cartes Edune

Ce que beaucoup devaient savoir

0 Cartes Jule EDOH

Le lapin

5 Cartes Christine Tourangeau

Anatomie membre inf

0 Cartes Axelle Bailleau

Créer des cartes mémoire