Vous êtes sur la page 1sur 63

Structure des ordinateurs

Bruxelles, le 30 novembre 2012


RISC et CISC

Bruxelles, le 30 novembre 2012


Architecture de Von Neumann
ADD A,55H

PROG ACC
PC

RAM ADDR
MEM
RAM

ALU

IR

UC
Architecture de Von Neumann
ADD A,55H

PROG ACC
PC

RAM ADDR
MEM
RAM

ALU

IR

UC
Architecture de Von Neumann
ADD A,55H

PROG ACC
PC

RAM ADDR
MEM
RAM

ALU

IR

UC
Architecture de Von Neumann
ADD A,55H

PROG ACC
PC

RAM ADDR
MEM
RAM

ALU

IR

UC
Architecture de Harvard

PROG ACC

RAM ADDR
PC
MEM
RAM

ALU

IR

UC
Architecture de Harvard

PROG ACC

RAM ADDR
PC
MEM
RAM

ALU

IR

UC
Architecture de Harvard

PROG ACC

RAM ADDR
PC
MEM
RAM

ALU

IR

UC
RISC et CISC
• Évolution
• Complexification continuelle toujours en cours pour certains processeurs dit
CISC (Complex Instruction Set Computer)

• > 1980 études démontrant une autre voie pour augmenter la performance : les
processeurs d’instruction réduit dis RISC (Reduced Instruction Set Computer)

• Clef de cette évolution : vitesse relative du CPU par rapport à la


mémoire
RISC et CISC (1946 – 1955)
• Technologie équilibrée
• CPU : tubes
• Mémoire : tubes
• Fréquence : quelques kHz
• Jeu d’instruction
• Très simple (RISC sans le savoir)
• Unité de commande câblée
• Programmation
• Von Neumann : concept de stored program
• Codage en langage machine
RISC et CISC (1955 – 1965) CPU plus rapide que mémoire
• Technologie
• Tube → transistor
• Accélération du CPU
• Processeur d’I/O, interruptions
• Mémoire à tores de ferrite
• Koctets
• Coût < tubes et transistors
• Faible consommation mais…
• Mémoire 10x plus lente que CPU

• Software
• Développement des langages évolués ou HLL (High Level Languages)
• FORTRAN, ALGOL, COBOL
RISC et CISC (1965 – 1969) CPU plus rapide que mémoire
• Facteurs d’évolution
• Technologie
• Transistors discrets → 1ers circuits intégrés
• Réduction du coût, de la taille et de la consommation
• Mémoires : tores de ferrite (↘) + semi-conducteurs (↗)
• Notion de cache
• Architecture
• UC micro-programmée
• Pipe-lining
• Software
• multiprecessing
• Systèmes d’exploitation multi-tâches
RISC et CISC (1970 – …) CPU et mémoire rapides
• Facteurs d’évolution
• Technologie
• Montée du niveau d’intégration
• Apparition des microprocesseurs
• Augmentation des fréquences d’horloge
• Mémoires à semi-conducteurs généralisées
• Rééquilibrage de la vitesse entre mémoire et CPU
• Software
• Recherches sur l’optimisation des compilateurs
RISC et CISC (1955 – …) la tendance CISC
• Double déséquilibre
• Vitesse CPU > vitesse mémoire
• La phase d’opcode/operand fetch est beaucoup plus lente que la phase de
décodage/execution
• sémantique
• Une instruction HLL est beaucoup plus riche que une instruction ASM
• Le compilateur traduit une ligne de source en de nombreuses instructions ASM
• Solution : CISC
• Créer des instructions machine complexes
• Pour facilité l’optimisation en assembleur
• Pour les rapprocher du langage de haut niveau
• Chaque instruction est optimisée indépendamment
RISC et CISC (1955 – …) la tendance CISC
• Réduction du déséquilibre sémantique
• Instructions machine plus complexes
• Réduction du déséquilibre de vitesse
• Moins d’accès mémoire
• Chaque opcode fetch ramène en moyenne une instruction plus complèxe, donc plus
riche
• Pallie partiellement la lenteur d’accès à la mémoire
• Plus de travail pour le CPU
• Décodage plus complexe
• Exécution plus longue
• Intéret des UC microprogrammées (flexibilité)

Diminuer le nombre de cycles machines en faisant des


opérations complexes dans chaque cycle
RISC et CISC (1955 – …) la tendance CISC
• Limitation du concept par le silicium de l’époque
• Taille de l’unité de commande microprogrammée
• Vitesse de la logique
• Ces limitations n’ont fait que décroitre → renforcement de la
tendance CISC
Jeu d’instructions CISC typique
• Contraintes des premières machines CISC
• Peu de mémoire (quelques Ko ou quelques 10Ko)
• Mémoire lente (temps d’accès 1ms)
• Programmation assembleur
• Caractéristiques fréquentes
• Format à deux opérandes, avec source et destination
• Registre vers registre
• Mémoire vers registre
• Registre vers mémoire
• Modes d’adressage multiples, avec modes spéciaux pour le parcours de tables
(arrays)
• Instructions de longueur variable, notamment à cause des variantes dans les
modes d’adressages
• Temps variable d’exécution
Architecture hardware CISC
• Logique complexe pour décodage d’instructions
• Liée aux multiples modes d’adressage pour chaque instruction
• Faible nombre de GPR (General Purpose Registers)
• Les instructions portent directement sur la mémoire
• Place limitée sur le silicium à cause du gros décodeur d’instruction
• Plusieurs SFR (Special Function Registers)
• Stack Pointer
• Masques d’intérruptions
• Registres d’adresse
• “Status” ou “Condition Code” reflétant le résultat de la dernière opération (=0,
!=0, signe, reports, erreurs)
La machine d’état CISC
• CISC : terminer une instruction avant la suivante
• Instruction en plusieurs étapes successives
• Extraction d’un op-code “op-code fetch”
• Décodage (+ extraction supplémentaires) pour identifier
• Le type d’opération
• Où sont les données (registres et/ou mémoire)
• Comment exécuter
• Où mettre le résultat (registres et/ou mémoire)
• Exécution proprement dite
• Écriture des résultats

• Idéalement
• Une instruction/cycle, 1cycle/coup d’horloge (irréaliste)
• En réalité
• Cycle divisé en étapes (“states”)
• Au moins 1 coup d’horloge par étape
• Un cycle = généralement plusieurs coups d’horloge
• Une instruction peut comporter plusieurs cycles
L’équation de performances
• Augmenter les performances
• ↗ fréquence d’horloge c-à-d ↘ 𝑇#$% et donc 𝑇&'&()
• ↘ 𝑁 (nombre total d’instructions) : typiquement CISC
• ↘ nombre de cycles / instruction : RISC mais aussi CISC

5
𝑡,-,_)/)& = 1 𝐶𝑃𝐼2 × 𝑇&'&()
234
Évolution des processeurs
4004 8008 8085 8086 80286 80386 80486 PI Ppro PII PIII PIV

date 1971 1972 1974 1978 1982 1985 1989 1993 1995 1997 1999 2000
clk[Hz] 100k 200k 2M 10M 12M 33M 50M 66M 200M 300M 1G 3G
Bus [bit] 4 8 8 16 16 32 32 64 64 64 64 64
#trans [K] 2.3 3.5 6 29 134 275 1200 3100 5500 7500 28K 42K
dim[µm] 10 10 6 3 1.5 1 .8 .8 .35 .35 .25 .13
mém adr[B] 640 16K 64K 1M 16M 4G 4G 4G 64G 64G 64G 64G
mém vir[B] --- --- --- --- 1G 64T 64T 64T 64T 64T 64T 64T
Intr 40 66 113 122 140 162 162 168 176 176 176 176
FP 91 91 91 91 91 91
MMX 47 47 47
SSE 64
SSE2 130
TOTAL 40 66 113 122 140 162 253 259 267 314 378 446
Conso[W] 3 6 13 44 25 34 55
1980 – … : réflexions de fond sur l’optimisation
• Augmentation de la vitesse d’accès à la mémoire
• Développement important des mémoires “caches”
• RAM statiques à accès rapides (quelques 10ns)
• En tampon entre mémoire programme et CPU
• Analyse du contenu de la cache pour l’optimiser
• Constatations
• Le déséquilibre de vitesse est inversé : cache plus rapide que CPU
• 80% du cache = instructions les plus simples
• Transfert mémoire ↔ registres
• Branchements
• …
1980 – … : réflexions de fond sur l’optimisation
• Jeu d’instructions complexes mal utilisé. Pourquoi ?
• Beaucoup d’instructions
• Difficile de programmer en assembleur ou d’optimiser un compilateur
• Beaucoup d’expérience pour bien programmer
• Optimisation en langage machine non univoque et difficile (trop de choix) : long à
personnaliser par rapport au développement d’un nouveau CPU
• On a finalement surtout recours à des instructions simples
1980 – … : réflexions de fond
• Compatibilité ascendante
• Poids du passé, malgré la disparition des contraintes de taille et de lenteur
mémoire et le passage ASM → HLL
• → complexité croissante
• Optimisation de la place mémoire mais …
• Instructions de taille et de temps d’exécution variables → difficile d’optimiser les
performances
• Est-ce encore nécessaire d’optimiser à ce point la taille du code ?
• Sous-utilisation des instructions spécialisées
• 20% du jeu utilisé en pratique
• → gaspillage du silicium consacré à une grosse Unité de Commande
• Bug hardware fréquents
• Status Register
• Mise à jour systématique prend du temps
• Le programmeur doit se souvenir d’aller le voir avant qu’il ne change
1985 – … : RISC
• Nombre d’instructions relativement limité (quelques dizaines)
• Toutes les instructions de même longueur et même durée
• Défaut : tend à gaspiller de la mémoire programme
• Architecture basée sur les registres
• Surface économisée sur UC consacrée à beaucoup de registres
• Architecture registre à registre
• RALU, instructions à 3 opérandes
• Pas d’instructions ALU vers mémoire : LOAD-STORE architecture
• Échange registre ↔ mémoire optimisé en un cycle (via cache)
• Orthogonalité (symétrie)
• Tous les registres sont équivalents
• Les instructions portent sur tous les registres
• Unité de commande simple et rapide (câblée)
• Peu d’instructions
• Limitation des modes d’adressage et pour LOAD et STORE seulement
• Interruptions simplifiées
1985 – … : RISC
• Bien réutiliser le silicium économisé
• Register file, fenêtrage
• Multiplieur câblé efficace
• Data-path multiples : architecture de Harvard
• Pipeline efficace
• Diminuer CPI par parallélisme d’exécution
• Optimum car toutes les instructions de même durée
1985 – … : RISC
• RISC prévu essentiellement pour HLL
• + de travail de base pour le software
• Gestion de stack
• Gestion d’interruptions
• …
• Nécessité d’un compilateur optimisé développé conjointement avec
le microprocesseur
1985 – … : RISC
• Savoir-faire de l’architecte
• Peu d’instructions mais choisir les bonnes
• Instructions = briques pour instruction plus complexes (comme CISC) fabriquées
par le compilateur et plus par le silicium
• La solution n’est pas unique
• Aucun processeur développé après 1985 n’est exempt de l’influence
RISC
• Plusieurs représentants
• MIPS, ARM, HP, DEC, Intel, MOTOROLA, SUN
RISC ou CISC ?
• Microprocesseur performant dans les 2 cas
• CISC
• Compatibilité ascendante (x86, 68K)
• Code plus compact
• Surtout destinés aux PC
• RISC
• Meilleure performance absolue
• Code moins compact
• Meilleur rapport performance/coût
• Meilleur rapport performance/consommation
• Surtout « embedded processors » et « workstations »

• Réconciliation
• RISC
• Tendance à augmenter le nombre d’instructions
• CISC
• Instructions prédécodées, puis exécutées par cœur RISC
• → réduction du CPI par les mêmes techniques que RISC
SISC
• Specific Instruction Set Computers
• Essentiellement micro-contrôleurs
• Tendance = RISC plus …
• Manipulation de bits
• Manipulation optimisée des périphériques internes (communication, graphique,
multimédia)
• Instructions spécifiques
• Special Function Register

• Fast Instruction Set Computers


Pipeline

Bruxelles, le 30 novembre 2012


Pipeline
• IF (Instruction Fetch) = (opcode cache → IR) || (PC = PC + 4)
• RD (Read & Decode) = (décodage instr) + (opérandes reg → RALU)
• EX (EXecute) = opération ALU
• Instruction arithmétique ou logique (𝑅2 OP 𝑅; )
• Branchement relatif (éventuellement conditionnel) : PC ± offset
• MA (Memory Access)
• Instruction LOAD ou STORE transfert mémoire ↔ cache
• Branchement conditionnel : PC = PC ± offset ou restaurer PC
• WB (Write-back cycle)
• Instruction arithmétique ou logique : sortie RALU → register (seule possibilité)
• LOAD : transfert cache → register

REM : MA pas toujours utile (uniquement LOAD, STORE, BRANCH)


Étapes de même longueur
Pipeline
Pipeline
• Types d’accidents
• Conflit de ressources (Structural Hazard) :
• Appel à la même ressource pour 2 instructions
• Dépendance de données (Data Hazard) :
• Une donnée requise n’est pas encore disponible
• Problème de controle (Control Hazard) :
• Branchements, interruptions, exceptions

• Conséquence : blocage temporaire, “bulle” et chute du rendement


• Solutions
• Software (compilateur)
• Insertion de NOP
• Permutation d’instructions (optimalisation)
• Hardware (marquage de registres)
Pipeline
Pipeline : ressource manquante
• Data path vers un banc de registre (pas moyen de faire 2 accès
successifs)
• Unité de traitement
• Data path vers la mémoire (exemple : cache unifiée → IF et MA
impossible si MA n’est pas vide (LOAD ou STORE en cours)
Pipeline : cache miss
• Rôle primordial des caches : accès en un cycle
• Idéal : débit cache = débit pipeline (en moyenne)
• Accident = cache miss (cache ne contient pas l’info voulue)
Pipeline : accidents entre 2 instructions
• RAW (Read After Write)
• 𝐼%<4 lit REG avant que 𝐼= n’y écrive → valeur erronée
• Le plus fréquent
• Peut être évité en multipliant les chemins de données (data forwarding) aux
différentes étapes du pipeline
• WAW (Write After Write)
• 𝐼%<4 écrit REG avant que 𝐼= n’y écrive → valeur erronée
• Seulement pipeline ou on écrit à plusieurs étapes
• WAR (Write After Read)
• 𝐼%<4 écrit REG avant que 𝐼= n’y lise → valeur erronée
• RAR (Read After Read) n’est pas un accident
Pipeline : RAW lors d’un accès à la cache

La donnée chargée par le LOAD n’est pas encore disponible lors de ce


cycle ; tenter d’utiliser la donnée à ce stade donne lieu :
• Soit à un résultat imprévisible
• Soit à une bulle si l’UC verrouille le pipeline
Le compilateur doit donc y placer
• Soit une instruction utile ne faisant pas appel à cette donnée
• Soit un NOP
Pipeline : RAW lors d’un accès à la cache

2 instructions inutiles chargées dans le pipeline entre l’instruction de


branchement et l’instruction cible vers laquelle on se branche
Pipeline : RAW lors d’un accès à la cache

Instruction du pipeline inutile → avortée


pénalité = durée du délai de branchement (2 cycles ici)
Pipeline : RAW lors d’un accès à la cache

Execution forcée des branch delay → le compilateur peut y placer


• Soit une instruction utile
• Prélevée avant le branchement
• Passage d’un paramètre dans un registre si CALL
• Soit un NOP
Pas utilisé pour les boucles
Pipeline : prédiction de branchement
If condition_C then instructionj else instructionk

• Vocabulaire
• Prendre le branchement = rupture de séquence (instruction suivante 𝑖; )
• Ne pas prendre = continuer l’incrémentation de PC (instruction suivante 𝑖= )
• Problème : délai de dépendance dans le pipeline
• L’instruction à exécuter (𝑖; ou 𝑖= ) n’est connue que lorsque la condition C a été
calculée et vérifiée
• Solutions
• Branchement avec délai
• Prédiction de branchement (>1990)
• On prend le branchement le plus probable (par ex 𝑖= )
• On commence à exécuter 𝑖= , 𝑖=<4 , 𝑖=<? « exécution spéculative » avant que C ne soit
connu
• Dès que C est connu
• Soit la prédiction était juste et on a gagné
• Soit la prédiction était fausse et on « détricote » (par exemple à l’aide d’une pile où on a
sauvé l’état avant de spéculer)
Pipeline : prédiction de branchement
• Simplement, mais bêtement
• Ne jamais (ou toujours) brancher
• Le plus naturel = ne jamais brancher c-à-d exécution séquentielle
• Implémentation hardware très simple
• 50% (?) de chance de prédire correctement
• Déjà mieux que de bloquer le pipeline systématiquement
• Un peu plus intelligemment
• Les boucles sont fréquentes
• Le branchement le plus probable est le retour au début
• → On branche si c’est « vers le haut »
• On ne se trompe qu’une fois : à la sortie de la boucle
Pipeline : prédiction de branchement
• Statique simple à un bit
• On associe 1 bit au branchement en cours qui mémorise le dernier état de la
condition C
• On suppose que C gardera la même valeur
• Marche très bien pour les boucles où seule la sortie change la condition C
• Taux de réussite moyen = 80%
• Statut graduel sur 2 bits
• NON(sûr) ↔ NON(probable) ↔ OUI(probable) ↔ OUI(sûr)
• 1er prédiction triviale : OUI(probable) ou NON(probable)
• évolution → si branchement effectivement pris, ← si pas pris
Les caches ou anté-mémoires

Bruxelles, le 30 novembre 2012


Organisation hiérarchique de la mémoire

Mémoire Mémoire
CPU
centrale de masse

Mémoire Mémoire
CPU Cache
centrale de masse

Mémoire Mémoire
CPU Cache
centrale de masse
Gérer la cache
• Buts :
• ↘ temps d’accès aux instructions et aux données
• Accès en 1 cycle → pipeline efficace
• Gérer la cache
• Contrôleur hardware (parfois intervention de l’OS)
• Rendre la cache transparente pour le programme
• Au moment où le processeur veut accéder à un mot, il doit pour bien faire déjà
se trouver dans la cache ; il faut donc prédire ce qu’il faut mettre en cache
• Savoir si l’adresse demandée se trouve dans la cache (cache hit) ou non (cache
miss)
• Aller chercher les données/instructions manquantes et savoir où les mettres
• Ne pas perdre de données
Principe de localité

• Cours terme : probabilité d’utiliser des adresses proches dans


l’espace ou dans le temps
• Long terme : déplacement des localités, il faut réactualiser
• ↗ de la taille de la cache : favorable (contenir toute une boucle)
Cache de disque
• Cache disque
• Mécanisme similaire
• Mémoire DRAM + rapide que disque
• Zone de DRAM = cache qui anticipe les besoins de données et instructions
• Beaucoup plus lent
• 𝑡@&&èB disque = quelques milisecondes
• Gérable en ”soft” par l’OS
• Mémoire virtuelle
• Prolongation virtuelle de la DRAM sur disque
• Également géré par OS
• Le precesseur doit être prévu pour
Gestion de la cache
Le principe de la gestion de la cache est d’abord la division en blocs :
On divise la cache en blocs, auquel on attribue un numéro
On divise la mémoire en blocs de la même taille, également numérotés
• Direct mapping ou correspondance directe
• Il n’y a qu’un bloc possible
• n°_bloc_cache = n°_bloc_mémoire MOD nombre_blocs_de_la_cache
• Fully associative ou cache associative
• n’importe quel bloc de cache est utilisable a priori et nous allons voir plusieurs
méthodes de choix de la sible
• N-way set associative ou cache partiellement associative
• On groupe les blocs pour former des ensembles (sets) de n blocs. Le numéro du
bloc en mémoire détermine que set sera la cible
• n°_set_cache = n°_bloc_mémoire MOD nombre_sets_de_la_cache
• Une fois le set fixé, on choisit un des n blocs du set par une méthode similaire à
la cache associative
Direct Mapping – Index et tag
• Supposons :
• Bloc de 16 (=2D ) mots
• Mémoire de 16M (=2?D ) mots → 2?E blocs en mémoire
• Cache de 4K (=24? ) mots → 2F blocs en cache
Direct Mapping – Structure et cache hit
Direct Mapping – Read miss : look aside et look through
• Look aside
• Lors d’un read hit, le contrôleur de cache branche le bus de données du CPU sur
la cache
• Lors d’un read miss le CPU accède directement en mémoire centrale à la
donnée qui lui manque (mais avec un temps d’accès plus élevé que pour la
cache). Ensuite, la mise à jour de la cache à lieu en transférant le bloc de
mémoire correspondant en cache
• Look through
• Le processeur n’a accès à sa mémoire centrale qu’à travers la cache
• Lors d’un read miss, on doit attendre le rafraîchissement de la cache (précédé
éventuellement de la mise à jour de la mémoire centrale) avant que le CPU ne
dispose du mot qu’il désire
Direct Mapping – write hit : write through
• Le CPU écrit à la fois dans la cache et la mémoire
• La mémoire est toujours à jour
• Un read miss n’entraine jamais de réécriture cache → mémoire
• Écritures plus lentes (mais beaucoup moins d’écritures que de
lectures)
• Sollicite plus le bus externe
Direct Mapping – write hit : write back
• Le CPU n’écrit que dans la cache
• Quand réécrire le bloc de cache en mémoire ? 2 solutions
• La plus simple : systématiquement au moment où l’on doit libérer le bloc
• La plus performante : en utilisant un Dirty bit
• Le bloc n’est recopié de la cache vers la mémoire que s’il a été modifié par le CPU, ce
qui entraine l’activation du bit M (Modifié) ou Dirty bit

• Plus efficace si on écrit beaucoup


• Plus difficile à gérer
• En cas de DMA
• Si tâche terminée ou interrompue alors que la cache contient encore des pages
qui la concerne
Direct Mapping – write miss
• Write-allocate ou fetch-and-write
• Similaire au read-thru : le bloc est chargé en cache avant modificaction
• Généralement associé au write-back : on espère que l’investissement de charger
tout le bloc sera amorti par d’autres modifications sur le même bloc
• No-write allocate ou write around
• La donnée est modifiée en mémoire sans mise à jour de la cache
• Souvent associé au write-through : on tient la mémoire centrale à jour en
permanence
Direct Mapping – bilan
• Avantages
• Gestion élémentaire, rapide, simple et compacte
• Calcul aisé de l’index et du TAG
• 1 seul comparateur de TAG
• Implémentation pratiquement réduite à une RAM
• Inconvéniants
• Cache trashing : si 2 blocs de mémoires fréquement utilisés à tour de rôle se
partagent le même bloc de cache, on passe beaucoup plus de temps à mettre la
cache à jour qu’a l’utiliser
• Placement modulo → ne se produit que pour des blocs séparés par taille de la
cache
• Trashing plus probable en cache mixte (unifiée)
Cache associative – TAG
• Supposons :
• Blocs de 16 (=2D ) mots
• Mémoire de 16M (= 2?D ) mots → 2?E blocs en mémoire
• Cache de 4K (= 24? ) mots en 256 blocs de 16 (= 2D ) mots
• N’importe quel bloc peut convenir → index n’a pas de sens
Cache associative – Structure et mécanisme de cache-hit
Cache associative – choix du bloc victime
• Aléatoire : tirage au sort
• Générateur pseudo-aléatoire simple
• Ne respecte pas le principe de localité
• Historique de la cache
• LRU (Least Recently Used)
• Remplacer le bloc le moins récemment accédé
• Respecte le principe de localité
• Historique lourd et vorace en silicium
• Souvant algorithme simplifié LRA (Least Recently Allocated)
• FIFO (First In First Out)
• Remplacer le plus ancien, accédé ou non
• Historique plus simple
• LFU (Least Frequently Used) ou MFU (Most Frequently Used)
• Basé sur un compteur d’accès pour chaque bloc
• Possibilité de verrouillage d’une partie stratégique de la cache
Avenue de l’Astronomie 19, 1210 Bruxelles – info@epfc.eu

Vous aimerez peut-être aussi