ES102 1 ARCHITECTURE DES MICROPROCESSEURS Couches logicielles Architecture (INTRODUCTION) Micro-architecture Logique/Arithmétique ES102 / CM8 Circuit logique Circuit analogique 8 Dispositif Physique 6 7 9 5 3 4 7 1 2 9 01/12/1990 ES102/CM8 2 DERRIÈRE VOTRE PROGRAMME C … swap(int v[],int k) { int temp; temp=v[k]; v[k]=v[k+1]; v[k+1]=temp; } C langage de l’embarqué, du calcul intensif et des systèmes d’exploitation ! IN102 instruction élémentaire exécutée en une (à quelques) période(s) d’horloge compilation langage machine swap: sll add lw lw sw sw jr $2 $2 $15 $16 $16 $15 $31 $5 2 $4 $2 0($2) 4($2) 0($2) 4($2) langage assembleur (variante lisible du langage machine) 00000000101000010000000000011000 00000000100011100001100000100001 10001100011000100000000000000000 10001100111100100000000000000100 10101100111100100000000000000000 10101100011000100000000000000100 00000011111000000000000000001000 exécution programme s’exécutant processus sur une machine dépend du type de machine visée Pour ce cours, choix de la famille de microprocesseurs MIPS ES102/CM8 3 BESOIN DE MÉMOIRE … • mémoire = tableau de bits, de largeur l, dont chaque ligne : R : read W : write – possède une adresse propre : son numéro, sur n bits – est accessible en lecture (RW = 1) ou en écriture (RW = 0) • sur présentation de son adresse adresse binaire / numérique 0 ···0000 0 0 ···0001 1 0 ···0010 2 0 ···0011 3 · · · · n 1 ···1110 2 -2 1 ···1111 2n-1 largeur : l bits 0110 ···············1010 0001 ···············1011 1111 ···············1111 1010 ···············1100 · · 1100 ···············0110 0100 ···············1111 bit porté par une cellule mémoire, détaillée au CM9 (en transistors) profondeur : 2n mots RW adresse contenu mémoire n bits din l M n l séquencement spécifique capacité : l · 2n bits dout ES102/CM8 4 … POUR MÉMORISER … • • ········ 11111111 int –1 ou typiquement sur 32 bits ou un multiple 11111111 unsigned int • sauf les caractères, sur 8 bits (= 1 octet) 11111111 4!294!967!295 – type char du C 11111111 " adressage octet par octet " l=8 char ‘E’ 01000101 " donnée 32 bits sur 4 lignes successives char ‘S’ 01010011 char ‘1’ 00110001 une adresse char ‘0’ 00110000 des adresses stockée en mémoire, char ‘2’ 00110010 sur 32 ou 64 bits ou dans un registre, 00000000 typiquement et il est est un pointeur ········ traité comme " espaces adressables : integer des données 232 = 4 gigaoctets (étroit) 264 = 16 exaoctets (immense) en langage C MI • 8 des instructions = signaux de commande de CD, et plus… • en partie codés une donnée MD adresse Mémoire d’instructions instruction lue 32 RW 32 32 MIPS I : tout en 32 bits Mémoire de données donnée écrite donnée adresse lue 32 32 ES102/CM8 5 BESOIN DE PLUS DE REGISTRES, AUSSI Registre load CK load 1 0 R load=1 : chargement nouvelle donnée load=0 : maintien ancienne donnée 1 0 1 0 1 0 d q dff d q dff d q dff d q dff CK CK CK CK • Multiples variables de calcul au cœur des algorithmes " Besoin de réaliser des opérations entre de multiples registres – extrême pauvreté de la «!calculette primitive!» : seulement 2 registres – à chaque cycle d’horloge, on souhaite pouvoir récupérer le contenu de n’importe quel couple de registres parmi de multiples accessibles, faire une opération sur les 2 opérandes ainsi récupérés, et ranger le résultat dans n’importe quel registre • C’est un banc de registres qui va répondre à ces besoins ES102/CM8 numéro de registre " adresse sw2’ sw1’ sw0’ sw2 sw1 sw0 SW 3 6 5 4 load6 load5 load4 32 R7 Décodeur d’adresse (PC4) SR1 = Select Read 1 SR2 = Select Read 2 SW = Select Write Exemple avec 8 registres 32 bits " 10kt CK SW SR1 SR2 data in data out1 data out2 load3 2 load2 1 load1 0 load0 7 6 6 5 5 4 4 3 3 2 2 1 1 0 0 R6 R5 R4 décodeur 3 7 multiplexeurs numériques 8 vers 1 un seul load à 1 load7 d_out 2 32 32 7 6 d_out1 d_in R3 R2 R1 R0 BANC DE REGISTRES 3 SR1 3 SR2 ES102/CM8 SW 3 BANC DE REGISTRES (2) SR2 SR1 SW lu1 lue1 écrit écrite 4 d_out 2 d_out 1 d_in 3 2 1 Registres souvent nommés autrement que par leur numéro, selon certaines spécificités : t0, s1, ra, a2, v0, sp… 0 load5 load4 load3 load2 load1 inutilisé 32 R7 a1 b 1 SOLU LU 0 1 2 3 0 1 2 3 0 =0 r1 6 6 5 5 4 4 3 3 2 2 1 1 0 0 R5 R4 R3 R2 R1 0 3 3 SR1 SR2 CHEMIN DE DONNÉES POUR PROCESSEUR a0 b 0 2 7 R6 R0 souvent remplacé par la constante numérique 0 et appelé registre zéro : - utile pour particulariser certaines opérations - permet de n’écrire sur aucun registre avec SW=000 ES102/CM8 7 multiplexeurs numériques 8 vers 1 Registres donnée lue2 6 load6 5 décodeur n° reg. lu2 load7 d_out 2 32 32 7 7 d_out1 d_in +/– SO : Select Operation # ÷ >0 =0 ALU = Unité Logique & Arithmétique r0 SO Registres SR2 SR1 SW n° reg. lu2 donnée lue2 lu1 lue1 écrit écrite ALU Instruction = { SR1, SR2, SO, SW } : les signaux de commande du CD 8 ES102/CM8 9 CHEMIN DE DONNÉES ÉTENDU Pas d’échange de données direct entre mémoire et ALU : architecture dite load-store Adresses mémoire élaborées par l’ALU : ce sont les pointeurs du langage C R/W Entrée din pour usage ultérieur spécifique L’instruction { SR1, SR2, SO, SW } se complexifie : R/W et commandes des MUX en plus SO din SR2 SR1 SW donnée lue2 lu1 lue1 écrit écrite donnée écrite donnée adresse lue >0 =0 1 0 Registres n° reg. lu2 Mémoire de données ALU 0 1 Bus multiplexés ES102/CM8 10 CODAGE DES INSTRUCTIONS • Redondance entre SO, R/W et les commandes des MUX ; cas inutilisés ! on code chaque instruction pour gagner en concision, en lui attribuant un numéro propre : le code opératoire R/W • sur 6 bits en MIPS • SR1, SR2 et SW restent en clair car indépendants/orthogonaux • sur 5 bits chacun car 32 registres en MIPS I • – instruction structurée en champs successifs instruction codée " décodage «!live!» nécessaire ! à la charge de l’UC (unité de commande) RI Registres op rs rt rd ··· SR1 32 SO din code opératoire sur 6 bits n° reg. lu2 r = reg. 5 SR2 lu1 d = dest. écrit 0 s = source 1 t = source/dest. SW op = code opératoire RI = Reg. d’instruction donnée lue2 lue1 Mémoire de données donnée écrite donnée adresse lue >0 =0 1 0 32 ALU 32 écrite Exemple ultérieur… 0 1 32 ES102/CM8 11 adresse Registre Program d’adresse Counter d’instruction (PC) 1 0 UC PARTIELLE 30 adresse Mémoire d’instructions 2 32 RI valeur immédiate 32 SR1 n° reg. lu2 r = reg. 5 SR2 lu1 d = dest. écrit 0 s = source 1 t = source/dest. SW op = code opératoire RI = Reg. d’instruction Registre d’adresse d’instruction Mémoire d’instructions instruction lue RI écrite ALU 0 1 depuis UC 1 0 CHARGEMENT INSTRUCTION SUIVANTE fUC • Mécanisme atomique pour état de l’UC adresse 32 lue1 adresse 30 32 donnée lue2 1 0 12 Program Counter (PC) décompte en instructions ici en octets (#4) là donnée écrite donnée adresse lue >0 =0 Registres op rs rt rd ··· ES102/CM8 32 1 instruction lue vers UC Mémoire de données 0 1 exécuter une suite prédéterminée d’opérations 2 32 0 1 gUC 1 - indépendante des données • UC : chaîne d’états liés par des transitions inconditionnelles valeur immédiate • Comportement implanté avec Registres op rs rt rd ··· n° reg. lu2 5 0 1 donnée lue2 lu1 lue1 écrit écrite une mémoire d’instructions (gUC) adressée par un compteur (fUC) • L’adresse présentée à la mémoire d’instructions est incrémentée de 4 à chaque période d’horloge pour désigner l’instruction suivante, située 4 octets plus loin, car largeur d’instruction = 32 bits ES102/CM8 13 INSTRUCTIONS • 3 types : – Opérations sur les données : • addition, soustraction, multiplication • opérations logiques • décalages (tournant ou pas), copie – Transferts de données : • de registre vers mémoire (écriture, store) de mémoire vers registre (lecture, load) 1 accès indirect aux données 2 I – Gestion de séquencement : • sauts (jump) et branchements (branch) • sous-programme : appel & retour (call & return) • fait intervenir les registres seulement R 3 J exploite pointeur sur mémoire de données procède par saut d’instructions (jump) exploite pointeur sur mémoire d’instructions environ 50 instructions au total, d’où 6 bits alloués au code opératoire ! passage en revue de 2-3 exemples caractéristiques pour chaque type – examen de leur réalisation sur CD + UC, voire de leur raison d’être – apprécier l’économie de moyens ES102/CM8 14 LE PREMIER MICROPROCESSEUR 4 Intel 4004 novembre 1971 Federico Faggin Ted Hoff Stan Mazor 3kt, pMOS 10µm, 740kHz, 16 registres entiers 4 bits, adresses 12 bits, 46 instructions 8 bits # MIPS I, où tout est sur 32 bits ES102/CM8 15 1 R ES102/CM8 16 adresse 1 0 compteur de programme : PC INSTRUCTION ARITHMÉTIQUE 1 R opérandes de l’instruction add add $t0,$s1,$s2 30 adresse Mémoire d’instructions 32 RI valeur immédiate n° reg. donnée lu2=s2 lue2 5 0 1 Mémoire de données 32 donnée écrite donnée adresse lue >0 =0 Registres op rs rt rd ··· r = reg. d = dest. s = source t = source/dest. op = code opératoire RI = Reg. d’instruction t0, s1, s2 : noms de registres 0 1 1 instruction lue 32 t0$$s1+$s2 2 lu1=s1 lue1 écrit=t0 écrite 1 0 32 ALU ALU = Unité Logique & Arithmétique 0 1 ES102/CM8 17 adresse 1 0 compteur de programme : PC … AVEC VALEUR IMMÉDIATE 1 addi $t0,$s1, 1 30 adresse Mémoire d’instructions 32 32 0 1 correspond à une ligne C t. q. k=j+1; valeur immédiate op rs rt rd ··· 5 r = reg. d = dest. s = source t = source/dest. op = code opératoire RI = Reg. d’instruction 0 1 Mémoire de données 32 1 1 RI t0$$s1+1 2 instruction lue R donnée écrite donnée adresse lue >0 =0 Registres n° reg. lu2 donnée lue2 lu1=s1 lue1 écrit=t0 écrite 1 0 32 ALU 0 1 Incrément 1 logé dans l’instruction même, au lieu d’être chargé dans un registre ES102/CM8 18 représentation en langage code opératoire de addi, à assembleur de l’instruction addi $t0,$s1, 1 décoder par l’UC, pour savoir d’addition immédiate comment exploiter le reste de l’instruction et piloter le CD registre n°17 : s1 la véritable registre n°8 : t0 instruction, 001000 10001010000000000000000001 sur 32 bits 32 entier 1 32 valeur immédiate 1 RI op rs rt rd ··· r = reg. 5 d = dest. 0 s = source 1 t = source/dest. op = code opératoire RI = Reg. d’instruction Mémoire de données donnée écrite donnée adresse lue >0 =0 Registres n° reg. lu2 donnée lue2 lu1=s1 lue1 écrit=t0 écrite 1 0 32 ALU 0 1 ES102/CM8 19 2 I La mémoire de données entre en jeu. Ci-après, la MD héberge un tableau d’entiers data, à partir d’une certaine adresse, adresse chargée dans le registre s1. L’élément data[5] se trouve donc à l’adresse $s1+20 pointeur ES102/CM8 20 adresse 1 0 compteur de programme : PC lw $t0,$s1+20 «!load word!» 30 adresse Mémoire d’instructions 2 32 op rs rt rd ··· 5 r = reg. d = dest. s = source t = source/dest. op = code opératoire RI = Reg. d’instruction 0 1 n° reg. lu2 donnée lue2 lu1=s1 lue1 écrit=t0 écrite 1 0 ! le registre t0 reçoit la valeur de data[5] (R/W=1) donnée écrite donnée adresse lue >0 =0 Registres I Mémoire de données 32 valeur immédiate 20 RI 0 1 2 R t0 reçoit le contenu de la mémoire à l’adresse $s1+20 1 instruction lue 32 CHARGEMENT DE DONNÉE 32 ALU 0 1 ES102/CM8 21 adresse 1 0 compteur de programme : PC sw $t0,$s1+20 «!store word!» 30 adresse Mémoire d’instructions 32 valeur immédiate op rs rt rd ··· n° reg. donnée lu2=t0 lue2 5 r = reg. d = dest. s = source t = source/dest. op = code opératoire RI = Reg. d’instruction lu1=s1 0 1 écrit (R/W=0) donnée écrite donnée adresse lue >0 =0 Registres I Mémoire de données 32 1 20 RI 0 1 2 W $t0 est stocké/écrit en mémoire à l’adresse $s1+20 2 instruction lue 32 STOCKAGE DE DONNÉE 1 0 32 ALU lue1 écrite 0 1 ! data[5] reçoit une nouvelle valeur, celle contenue dans le registre t0 ES102/CM8 22 3 J Jusqu’ici, la prochaine instruction exécutée était la suivante en mémoire d’instructions (fUC : compteur). Mais, casser parfois cette routine va s’avérer d’un grand intérêt. Idée : utiliser des instructions dédiées pour altérer le fonctionnement du compteur. ES102/CM8 23 IF THEN ELSE Le if … : … du Python est un if … then … en C if if else then after adresse en mémoire t A l’exécution, selon le résultat du test if, on exécute soit then soit else J ex. avec else supposée de longueur 8 : else then 3 Besoin d’un branchement (branch) qui, selon le résultat du test if, saute vers then ou poursuit avec l’instruction suivante, débutant ainsi else En mémoire d’instructions, ces segments de code sont installés les uns derrière les autres : les segments else et then doivent donc pouvoir être sautés. beq $s1, $s2, +9 (branch if equal) Si $s1=$s2, sauter 9 instructions plus loin, sinon avancer à la suivante (comme d’habitude). Une fois else exécuté, besoin d’un saut (jump) systématique par dessus then pour atteindre after j BeginAfter (jump) BeginAfter = adresse symbolique, aussi appelée étiquette, de la première instruction du segment after. ES102/CM8 24 adresse SAUT 1 0 compteur de programme : PC jump j There 30 adresse Mémoire d’instructions 2 32 0 1 32 There RI valeur immédiate Registres op rs rt rd ··· n° reg. lu2 5 r = reg. d = dest. s = source t = source/dest. op = code opératoire RI = Reg. d’instruction 0 1 donnée lue2 lu1 lue1 écrit écrite donnée écrite donnée adresse lue >0 =0 26 1 0 C’est au vu du code opératoire de j que l’UC dirige There vers le PC J Mémoire de données 32 1 instruction lue 3 saut à l’adresse «!There!» de la mémoire d’instructions 32 ALU 0 1 ES102/CM8 25 adresse 1 0 compteur de programme : PC «!repère!» relatif à l’instruction courante Mémoire d’instructions 2 O_o le CD pilote l’UC ? valeur immédiate op rs rt rd ··· 0 1 écrit 32 donnée écrite donnée adresse lue 1 0 Registres lu1=s1 Mémoire de données >0 =0 16 n° reg. donnée lu2=s2 lue2 5 r = reg. d = dest. s = source t = source/dest. op = code opératoire RI = Reg. d’instruction 0 1 1 +9 RI J branch if equal 32 instruction lue 32 3 beq $s1,$s2,+9 30 adresse BRANCHEMENT 32 ALU lue1 0 1 écrite Branchements vers l’arrière utiles également, pour les boucles while ES102/CM8 26 SOUS-PROGRAMMES ··· n=fact(k); ··· ··· int fact(int i) { ··· } Déclaration d’une fonction en C return_add 3 J Appel jal : jump and link - saute vers add_fact et mémorise return_add dans le registre ra Retour jr $ra : jump register - saute vers l’adresse contenue dans le registre ra Quelque part en mémoire ··· jal add_fact ··· ··· ··· ··· Quelque part ailleurs en mémoire add_fact appel retour ··· ··· ··· ··· ··· ··· ··· jr $ra Sousprogramme «!fact!» ES102/CM8 27 RESTE DE L’UC adresse 1 0 compteur de programme : PC Outre charger l’instruction, il faut la décoder puis l’exécuter 30 adresse Mémoire d’instructions 2 32 RI Mémoire de données 0 1 32 1 instruction lue valeur immédiate 32 R/W Unité de commande >0 =0 1 0 Registres op rs rt rd ··· n° reg. lu2 5 0 1 donnée écrite donnée adresse lue donnée lue2 lu1 lue1 écrit écrite 32 ALU 0 1 ES102/CM8 28 PIPE-LINE L’instruction lw (load word) de chargement de données apparaît la plus longue : – 5 étapes successives irréductibles : • lecture/décodage de l’instruction • lecture du registre portant l’adresse de base du tableau où se trouve la donnée en mémoire • calcul de l’adresse de la donnée, à partir de son indice, passé en valeur immédiate, et de la base • récupération de la donnée en provenance de la mémoire • écriture dans un registre MI Mémoire d’instructions Reg Banc de registres : lecture ALU MD Mémoire de données Reg Banc de registres : écriture petit segment de code – tentant de pipeliner ces 5 étapes en 5 étages : Mais : CK lw $t0,0($t1) bne $t0,$s3,Exit add $s1,$s1,$s2 instruction exécutée MI Reg MD MI Reg ? MI Reg MD Reg comment utiliser $t0 alors qu’il n’est pas encore calculé ? ? Reg MD Reg quid de charger une instruction sans savoir si c’est la bonne ? ! C’est à l’UC de gérer… ES102/CM8 29 APU Kabini (4 cœurs Jaguar) JAGUAR CORE Instr. tag / TLB Branch predict Instruction cache µcode ROM x86 Decode Integer Debug Data tag / TLB ReOrder Buffer Bus unit Load / Store Data cache Floating point Test Cœur 64 bits entier / 128 bits flottant 2 voies - out of order - cache L1 64ko 3,1mm2 en CMOS 28nm basse consommation prod. 2S13 Xbox One (8 cœurs Jaguar) AUC " ACD ici, AUC > ACD en général 15W@1,5GHz - 25W@2GHz cache L2 2Mo partagé