You are on page 1of 177

ARCHITECTURE

DES ORDINATEURS
THÉORIE

François SCHUMACKER, Ir

Bloc 1 – Bachelier en Informatique


Année académique 2023-2024
Ce document est disponible sous licence Creative Commons indiquant qu’il peut être
reproduit, distribué et communiqué pour autant que le nom des auteurs reste présent,
qu’aucune utilisation commerciale ne soit faite à partir de celui-ci et que le document ne
soit ni modifié, ni transformé, ni adapté.

http://creativecommons.org/licenses/by-nc-nd/2.0/be/

La Haute École Libre Mosane (HELMo) attache une grande importance au respect des
droits d’auteur. C’est la raison pour laquelle nous invitons les auteurs dont une œuvre
aurait été, malgré tous nos efforts, reproduite sans autorisation suffisante, à contacter
immédiatement le service juridique de la Haute École afin de pouvoir régulariser la
situation au mieux.
Architecture des ordinateurs - Théorie Introduction

Introduction
Objectif
L’objectif premier du cours d’architecture des ordinateurs est de présenter l'aspect matériel de
l'informatique : les architectures d’ordinateurs existantes, le fonctionnement des composants les
plus courants, les méthodes de représentation et de codage de l’information.

À la fin de ce cours, l’étudiant sera capable de :


• Décrire la structure générale d’un ordinateur, identifier ses principaux composants,
comprendre les différences entre les architectures les plus courantes.
• Comprendre et utiliser les principales techniques de représentation et de codage de
l’information.
• Comprendre le fonctionnement de circuits logiques élémentaires.
• Comprendre l’organisation et expliquer le fonctionnement des éléments constitutifs d’un
ordinateur (CPU, mémoires, entrées/sorties, langage d’assemblage, système d’exploitation
…).
• Comprendre le principe et l’intérêt des techniques de parallélisme.

Contenu des différents chapitres


1. Histoire de l’informatique
Ce chapitre donne un aperçu de l'histoire de l'informatique, de l'antiquité à nos jours. Quels
sont les jalons importants dans l'évolution des connaissances, de la science et des
technologies qui ont permis l'éclosion de l'industrie informatique telle que nous la
connaissons aujourd'hui ? Nous nous intéressons également aux principaux éléments qui
conditionnent l'évolution des performances des ordinateurs, afin de mieux comprendre les
fondements des architectures actuelles, ainsi que les enjeux de demain.
2. Présentation générale d’un ordinateur
Qu’est-ce qu’un ordinateur ? Du simple gadget électronique jetable aux centres de données
géants du « Cloud Computing », l’ordinateur est partout. Dans ce chapitre, nous tenterons
d’identifier les composants principaux d’un ordinateur et nous expliquerons comment ils
sont organisés.
3. Le codage des informations
L’informatique est le traitement automatisé de l’information. Comment peut-on représenter
les informations à traiter dans un ordinateur ? Ce chapitre présente les techniques utilisées
pour coder des informations numériques et textuelles, détecter et corriger d’éventuelles
erreurs, réduire la taille occupée par ces informations.

© HELMo Campus Guillemins i


Introduction Architecture des ordinateurs - Théorie

4. Les circuits logiques


Les ordinateurs actuels ont une puissance de calcul phénoménale et peuvent réaliser des
tâches extraordinairement complexes. Et pourtant, leur fonctionnement repose sur des
« briques de base » extrêmement simples. Ce chapitre nous rappelle les principes de
l’algèbre de Boole et nous explique comment des portes logiques très simples peuvent être
combinées pour former les circuits logiques élémentaires qui sont à la base du
fonctionnement d’un ordinateur, telles que les unités de calcul ou les mémoires.
5. L’unité centrale de traitement (CPU)
L’unité centrale de traitement constitue le centre névralgique de l’ordinateur. C’est elle qui
exécute les instructions d’un programme, traite les données fournies pour produire des
résultats utiles. Quelles sont les tâches réalisées par le CPU ? Comment représenter les
instructions d’un programme ? Comment les exécuter ? Comment maximiser les
performances du CPU ? Telles sont les questions auxquelles nous tenterons de répondre
dans ce chapitre.
6. Les mémoires
Comment stocker les informations dans un ordinateur et pour quels besoins ? Quelles sont
les technologies disponibles ? Comment équilibrer la balance coût/performance ? Comment
augmenter les performances avec une antémémoire (cache) ? Ce chapitre nous livre tous les
secrets (ou presque) de la hiérarchie des mémoires.
7. Les entrées et sorties
Pour réaliser des tâches utiles, un ordinateur ne fonctionne pas en vase clos. Il doit pouvoir
communiquer avec son environnement afin d’obtenir les informations qui lui sont
nécessaires (programmes, données), communiquer les résultats de son travail et interagir
avec l’utilisateur. Dans ce chapitre, nous nous intéressons aux mécanismes de
communication entre les composants d’un ordinateur, ainsi qu’entre l’ordinateur et le
monde extérieur proche (périphériques) ou lointain (réseaux).
8. Le système d’exploitation
Un ordinateur est une machinerie complexe composée de nombreux éléments qui doivent
interagir de manière harmonieuse afin de réaliser une multitude de tâches. Comment
organiser ces tâches, gérer les ressources disponibles, simplifier la vie de l’utilisateur final ?
Tel est le rôle du système d’exploitation, que nous abordons dans ce chapitre.
9. Les architectures à processeurs multiples
L’augmentation de la performance des ordinateurs permet de résoudre aujourd’hui des
problèmes extrêmement complexes. Les lois de la physique et les limites technologiques
actuelles ne permettent toutefois pas d’augmenter indéfiniment la puissance d’un seul
ordinateur. L’augmentation des performances passe désormais par la conception
d’architectures à processeurs multiples. C’est le sujet de ce dernier chapitre.

ii © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Histoire de l’informatique

11 Histoire de l’informatique
1.1 Des nombres et des hommes
La nécessité de savoir compter est apparue très tôt dans l’histoire de l’humanité. Le comptage servait
initialement à quantifier ses propres richesses : nombre de têtes de bétail, volume des récoltes, etc.
Les échanges commerciaux n’ont fait que renforcer ce besoin de comptage.
Les premiers systèmes de comptage étaient basés sur des techniques très simples. À un nombre
donné (quantité dénombrée) correspondaient un nombre équivalent d’éléments physiques :
encoches dans le bois, cailloux (provient du latin calculus, origine du mot calcul), nœuds dans une
corde, jetons, etc. La quantité dénombrée était donc uniquement fonction du nombre d’éléments
utilisés lors du comptage. Les opérations arithmétiques étaient elles aussi très simples : on ajoutait
ou l'on retirait un certain nombre d’éléments.
L’étape suivante fut l’invention des chiffres. Un chiffre est la représentation symbolique d’un
nombre. Les différents chiffres sont matérialisés soit par des objets (p. ex., jetons d’argile) de formes
différentes, soit par un symbole scriptural (barres sur jeton d’argile, hiéroglyphes, chiffres romains,
chiffres arabes…).

Chiffres romains : I, II, III, IV, V, VI, VII, VIII, IX, X, … (pas de zéro)
Chiffres arabes : 1, 2, 3, 4, 5, 6, 7, 8, 9 (toujours pas de zéro 0, il sera inventé plus tard)

Les systèmes de numération primitifs ne sont pas pratiques lorsqu’il s’agit de représenter de grands
nombres. L’homme invente alors la numération de position qui permet de représenter de très
grands nombres d’une manière compacte. La valeur (poids) accordée à un chiffre dépend désormais
de la position à laquelle ce chiffre apparaît dans l’écriture d’un nombre, ainsi que de la base utilisée
par le système de numération.

En base dix : 1234 signifie 1x1000 + 2x100 + 3x10 + 4x1

Avec la numération de position apparaît la nécessité d’inventer le zéro, c’est-à-dire de disposer d’un
chiffre particulier qui représente une absence de valeur dans une position donnée.

Le zéro permet de distinguer 12, 120, 1200, 102, 1002, … sans ambiguïté.

En revanche, on peut constater qu’en base décimale, il n’y a plus de symbole spécifique pour
représenter le nombre 10. Les dix symboles de la base sont : 0, 1, 2, 3, 4, 5, 6, 7, 8 et 9.

La base utilisée par le système de numération a beaucoup varié en fonction des peuples, des
époques, ou des usages. Le tableau ci-dessous présente un résumé des systèmes de numération les
plus connus.

© HELMo Campus Guillemins Page 1.1


Histoire de l’informatique Architecture des ordinateurs - Théorie

Base Nom Usage Origine


1 unaire Comptage (doigts, cailloux, entailles…)
2 binaire Logique, électronique, informatique
5 quinaire Aztèques (doigts d’une main)
7 septénaire Jours de la semaine, notes (tons)
8 octal Informatique Premiers ordinateurs
10 décimal Système de numération le plus répandu Chinois (doigts des 2 mains)
12 duodécimal Mois, heures, musique (tons + demi-tons) Egyptiens
16 hexadécimal Informatique
20 vicésimal Mayas (doigts + orteils)
60 sexagésimal Trigonométrie (angles), minutes, secondes Babyloniens, indiens, arabes…
Figure 1-1 - Quelques systèmes de numération

1.2 Deux millénaires de progrès…


• 500 av JC – Abaques : bouliers, tables à compter, bâtons de Neper.
• 1614 – John Neper (mathématicien écossais) invente la théorie des logarithmes qui donnera
naissance à la règle à calcul. En effet, grâce aux logarithmes, il est possible de remplacer la
multiplication (ou la division) de deux nombres par l’addition (ou la soustraction) de leurs
logarithmes : log(𝑎 × 𝑏) = log(𝑎) + log⁡(𝑏) et log(𝑎 ÷ 𝑏) = log(𝑎) − log⁡(𝑏).
• 1623 – Wilhelm Schickard (universitaire allemand) conçoit une machine à calculer
mécanique qui reprend l’idée des bâtons de Neper.
• 1642 – Blaise Pascal (philosophe et scientifique français) invente une machine à calculer
dénommée la Pascaline qui permet principalement d’additionner et de soustraire deux
nombres de 6 chiffres. Multiplication = répétition d’additions.
• 1673 – Gottfried Wilhelm Leibniz (philosophe et scientifique allemand) améliore la Pascaline
et conçoit une machine pouvant également réaliser des multiplications et des divisions
directes. Il invente également le système binaire et l’arithmétique binaire qui sont à la base
des ordinateurs actuels.
• 1805 – Joseph Jacquard (inventeur français) invente le premier système de programmation. Il
utilise des bandes de carton perforées (ancêtre de la carte perforée) pour créer de manière
automatique des motifs complexes sur un métier à tisser. Les motifs Jacquard sont encore
fréquents de nos jours!
• 1822-1833 – Charles Babbage (mathématicien anglais) invente une machine à différences
pour réaliser des tables de calculs (navigation, astronomie…) exactes. Il conçoit ensuite la
machine analytique, qui permet de réaliser différentes opérations en fonction d’un
programme établi sur des cartes perforées. (Collaboratrice = Ada Augusta)
• 1854 – George Boole (logicien, mathématicien et philosophe anglais) invente les bases
mathématiques de la logique moderne. L’algèbre de Boole (ou booléenne) est à la base de la
conception des circuits électroniques digitaux qui ont permis la création des ordinateurs
modernes.
• 1890 – Herman Hollerith (ingénieur américain) construit un calculateur de statistiques à
cartes perforées pour accélérer le recensement de la population américaine. En 1896, il
fonde la Tabulating Machine Company, qui deviendra finalement l’International Business
Machines Corporation (IBM) en 1924.

Page 1.2 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Histoire de l’informatique

• 1904 – John Ambrose Fleming (physicien et ingénieur anglais) invente le premier tube à
vide : la diode à vide.
• 1936 – Alan Turing (mathématicien, cryptologue et informaticien anglais) publie un article
dans lequel il traite de la possibilité théorique de résoudre (ou non) des problèmes
mathématiques. Il présente une machine universelle, appelée machine de Turing, susceptible
de résoudre tout problème calculable. Il est ainsi à l’origine de la formalisation des concepts
d’algorithme et de calculabilité.
• 1938 – Claude Shannon (ingénieur et mathématicien américain) est le père fondateur de la
théorie de l’information dans laquelle il effectue la synthèse entre les nombres binaires,
l’algèbre de Boole et l’électronique.
• 1936 à 1941 – Konrad Zuse (ingénieur allemand) construit les premiers calculateurs
électromécaniques (Z1 et Z2) basés sur le système binaire. En 1941, le Z3 est un calculateur
universel composé de 2600 relais. Il réalise une multiplication en 5 secondes.
• 1944 à 1947 – Howard Aiken (Harvard) conçoit le Mark I. Énorme calculateur
électromécanique. 72 registres de 23 chiffres décimaux. Multiplication en 6 secondes.
Addition et soustraction en 0,3 seconde.
Son successeur, le Mark II, utilise des relais électromagnétiques rapides, ce qui lui permet de
gagner un facteur de vitesse de 2,6x pour les additions et de 8x pour les multiplications. Il
intègre également des fonctions mathématiques telles que l'inverse, la racine carrée, le
logarithme, l'exponentielle et certaines fonctions trigonométriques en version matérielle.
L’histoire raconte que, le 9 septembre 1947, un papillon de nuit se serait bloqué dans un
relais du calculateur, provoquant ainsi le premier bug informatique !
Les calculateurs Mark sont obsolètes dès leur construction, car l’ère de l’électronique
commence…

1.3 Évolution des ordinateurs


1.3.1 Première génération : les tubes à vide (1945 – 1955)
Composants : relais, tubes à vide, résistances.
Logiciels : langage machine seulement.

• 1943 – COLOSSUS : premier ordinateur électronique digital (secret militaire).


• 1945 – ENIAC (Electronic Numerical Integrator And Computer)
o Architecture à base de lampes et tubes à vide : 18.000 tubes, 1.500 relais, 140 kW de
consommation électrique, 30 tonnes, 170 m2 au sol !
o 20 registres de 10 chiffres décimaux.
o 5.000 additions par seconde, multiplication en 0,3 milliseconde.
o Programmation peu pratique : 6.000 interrupteurs, une multitude de prises et une
forêt de câbles.
o Données sur cartes perforées.

© HELMo Campus Guillemins Page 1.3


Histoire de l’informatique Architecture des ordinateurs - Théorie

• 1945 – John von Neumann (avec Eckert et Mauchley) propose une évolution de l’ENIAC,
appelée EDVAC (Electronic Discrete Variable Automatic Computer). Toutefois, il est
indispensable de résoudre le problème majeur de l’ENIAC : sa programmation très
laborieuse.
John von Neumann a une idée géniale pour faciliter la programmation d’un ordinateur : il
propose une architecture basée sur un système de commande universel. Celui-ci est
contrôlé par un programme dont les instructions sont codées en binaire et stockées en
mémoire, au même titre que les données. L’ordinateur moderne est né !

L’architecture de von Neumann


Caractéristiques :
o Machine universelle contrôlée par un programme.
o Instructions codées en binaire et stockées en mémoire.
o Le programme peut modifier ses propres instructions.
o Exécution des instructions en séquence, sauf lorsqu’une instruction provoque
une rupture de séquence (branchement, saut).

Mémoire

Unité
Unité de arithmétique Entrée
contrôle et logique
Accumulateur
Sortie

Figure 1-2 - L’architecture de von Neumann


Composants :
o Unité de contrôle : gère l’exécution du programme.
o Unité arithmétique et logique (ALU) : effectue les opérations mathématiques.
o Mémoire centrale : contient le programme et les données.
o Dispositifs d’entrée et sortie : pour communiquer avec le monde extérieur.

L’architecture (ou machine) de von Neumann constitue une véritable révolution dans la
manière de concevoir un ordinateur, car elle propose une architecture dans laquelle le
programme est enregistré en mémoire (« stored-program » concept), ce qui la rend très
facile à programmer. L’unité de contrôle détermine la logique d’exécution d’un programme.
Le programme est quant à lui défini par une séquence d’instructions stockées en mémoire
sous la forme d’un code binaire. Il est donc aisément modifiable.
La plupart des ordinateurs actuels sont toujours basés sur cette architecture !
Cette architecture n’est pas parfaite. Avec elle apparaît notamment le goulot
d’étranglement de von Neumann : la vitesse de transfert des instructions et des données
entre le processeur et la mémoire est limitée, ce qui réduit sérieusement la vitesse de
traitement effective du processeur. Le problème s’aggrave d’autant plus que la vitesse des
processeurs et la taille des mémoires augmentent. Différentes solutions techniques sont
mises en œuvre pour limiter l’impact du goulot d’étranglement de von Neumann sur les
performances. La mémoire cache est l’une d’entre elles, nous en parlerons au chapitre 6.

Page 1.4 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Histoire de l’informatique

• 1949 – Maurice Wilkes construit l'EDSAC (Electronic Delay Storage Automatic Calculator).
Premier ordinateur basé sur l’architecture de Von Neumann. 5.000 opérations mathématiques,
dont 4.000 multiplications par minute.

• 1951 - Eckert et Mauchley construisent l'UNIVAC (UNIVersal Automatic Computer). 5.200 tubes à
vide, 13 tonnes, 1.905 opérations par seconde. Données stockées sur une bande magnétique.

• 1953 – IBM lance l’IBM 701 : 16.000 additions ou 2.200 multiplications par seconde. Viendront
par la suite des versions améliorées (IBM 704 et IBM 709), ainsi que l’IBM 650.

1.3.2 Deuxième génération : les transistors (1955 – 1965)


Composants : transistors, mémoire à tores de ferrite, imprimantes, bandes magnétiques.
Logiciels : apparition des systèmes d'exploitation, langages évolués FORTRAN (1957), COBOL (1959).

• 1948 – Invention du transistor par John Bardeen, Walter Brattain et William Shockley
(laboratoires Bell).
o Les transistors remplacent les tubes : accroissement de la vitesse et de la fiabilité.
Diminution des coûts de fabrication.
o Essor de l’informatique et naissance des grands acteurs du secteur : DEC, HP, Data
General, …
• 1960 – DEC PDP-1 ($120.000) : le premier « mini-ordinateur ». Mémoire de 4.096 mots de 18
bits. 200.000 instructions par seconde. Premier écran graphique (512x512) et premier jeu vidéo !
• 1962 – IBM 7094 : domine le monde du calcul scientifique au début des années 60.
• 1965 – DEC PDP-8 ($18.000) : le premier ordinateur de masse avec 50.000 exemplaires vendus. Il
introduit le concept de bus pour interconnecter les différents éléments de l’ordinateur.
• 1964 – CDC 6600 (conçu par Seymour Cray): premier superordinateur scientifique. Il introduit la
notion de parallélisme (plusieurs unités fonctionnelles travaillent en même temps) et de
coprocesseurs pour s’occuper de la gestion des tâches et des entrées/sorties.

1.3.3 Troisième génération : les circuits intégrés (1965 –


1970)
Composants : circuits intégrés (faible consommation, fiables, encombrement réduit).

De nouvelles fonctionnalités apparaissent : multiprocesseur, systèmes d’exploitation multitâches,


accès interactif, réseaux …

• 1958 – Premier circuit intégré (Texas Instrument) = nombreux composants dans un seul boîtier.
• 1964 – IBM System/360 : première gamme d’ordinateurs (modèles 30/40/50/65) compatibles
entre eux, mais proposant des puissances croissantes selon les besoins des utilisateurs.
Multiprogrammation (plusieurs programmes en mémoire). Émulation des modèles précédents
(1401 et 7094) par la technique de la microprogrammation.
• 1969 – Système d’exploitation MULTICS (Bell), un ancêtre de UNIX.

© HELMo Campus Guillemins Page 1.5


Histoire de l’informatique Architecture des ordinateurs - Théorie

1.3.4 Quatrième génération : les microprocesseurs (1970 –


????)
Composants : microprocesseurs, intégration à très large échelle (VLSI).

La miniaturisation permet une forte augmentation de la puissance tout en diminuant les coûts et
l’encombrement. Cela permet l’éclosion de la micro-informatique et l’apparition de l’ordinateur
personnel (PC).

Périphériques de grande capacité, imprimantes laser de haute qualité, écrans graphiques en couleur.

La convergence numérique s’amorce.

• 1971 – Premier microprocesseur : 4004 d’Intel (4 bits, 740 KHz, 2.300 transistors, 90.000
opérations par seconde). Une puissance similaire à celle de l’ENIAC : 0,092 MIPS.
• 1972 – Microprocesseur 8008 d’Intel (8 bits, 200 KHz, 3.500 transistors).
• 1973 – Langage C pour le développement d’UNIX.
• 1974 – Premier microprocesseur Motorola : 6800 (8 bits) [TRS-80, Apple II, …].
• 1978 – Microprocesseur 8086 d’Intel (16 bits, 4,77 MHz, 0,33 MIPS). Famille x86.
• 1981 – IBM Personal Computer : design public et donc copié ! (Intel 8088).
• 1984 – Apple Macintosh (Motorola 68000, processeur 16/32bits). Première interface graphique
grand public. Puissance : 1,4 MIPS.
• À partir de 1986 – Processeurs Intel (32 bits) : 80386, 80486, Pentium, Pentium Pro, Pentium II,
Core.
• À partir de 2000 – Processeurs Intel (64 bits) : Pentium 4, Pentium D, Core 2, Core i3, Core i5.
• 2011 – Processeur Intel Core i7 2600K : 64 bits, 1,4 milliard de transistors, 3,4 GHz, 4 cœurs, 8
threads, 128.300 MIPS, gravure 32 nm.
• 2014 – iPhone 6 : 64 bits, 2 milliards de transistors, 1,4 GHz, 25.000 MIPS.
• 2014 – Processeur Intel Core i7 5960X : 64 bits, 2,6 milliards de transistors, 3,5 GHz, 8 cœurs, 16
threads, 238.300 MIPS, gravure 22 nm.
• 2016 – Processeur Intel Xeon Broadwell E5 : 64 bits, 7,2 milliards de transistors, 2,2 GHz, 22
cœurs, 44 threads, gravure 14 nm.
• 2016 – GPU Nvidia GP100 Pascal : 15,3 milliards de transistors, gravure 16 nm, >9.500 GFLOPS !!!
• 2020 – iPhone 11 Pro : 64 bits, 6 cœurs, 8.5 milliards de transistors, gravure 7nm, ≃155 GFLOPS
• 2020 – AMD 3990X : 64 cœurs, 128 threads, 2.9-4.3 GHz, 40 milliards de transistors, >3.700
GFLOPS

Page 1.6 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Histoire de l’informatique

1.4 Évolution des performances


1.4.1 La loi de Moore
À partir des années 70, les progrès technologiques sont très rapides. L’intégration de plus en plus
poussée des composants sur une puce permet également une augmentation régulière de la
puissance de calcul et de la capacité de stockage de la mémoire centrale.

En 1965, Gordon Moore (cofondateur d’Intel) constate que depuis 1959 la complexité des circuits
intégrés à base de transistors double tous les ans à coût constant. Il postule que cette croissance
exponentielle va se poursuivre. Ce postulat fut rapidement nommé « (première) loi de Moore ».

En 1975, Moore réévalue sa prédiction et estime que le nombre de transistors sur une puce de
silicium (microprocesseurs, mémoires) doublera tous les deux ans. Cette extrapolation empirique
porte le nom de « deuxième loi de Moore ». Elle s’est révélée très proche de la réalité, puisqu’entre
1971 (date du premier microprocesseur Intel 4004) et 2010 la densité des transistors a effectivement
progressé d’un facteur très proche de 2 tous les deux ans.

Une autre version fréquemment rencontrée, qui est pourtant sans lien avec les énoncés de Moore,
est que d’autres caractéristiques (puissance, capacité, fréquence d’horloge…) doublent tous les 18
mois. Cet énoncé n’est clairement plus vérifié depuis le début des années 2000 en ce qui concerne la
fréquence d’horloge à cause des problèmes de dissipation thermique.

Figure 1-3 - Illustration de la Loi de Moore


Source: original téléversé par QcRef87 sur Wikipédia français. — Transféré de fr.wikipedia à Commons par Bloody-libu utilisant CommonsHelper., CC BY-SA 3.0,
https://commons.wikimedia.org/w/index.php?curid=16066564

© HELMo Campus Guillemins Page 1.7


Histoire de l’informatique Architecture des ordinateurs - Théorie

1.4.2 Avantages et inconvénients de l’intégration à large


échelle
L’intégration de plus en plus poussée des composants offre de nombreux avantages :

• Augmentation de la capacité des puces mémoires.


• Augmentation de la vitesse intrinsèque des composants (distances plus courtes) et donc de la
fréquence d’horloge de l’ordinateur (augmentation du nombre d’instructions par seconde).
• Processeurs de plus en plus sophistiqués et performants.
• Plusieurs composants sur une seule puce (cores / cœurs, mémoire cache).

Malheureusement, les lois de la physique imposent des limites incontournables :

• Il n’est pas possible de réduire indéfiniment la taille d’un transistor. Les transistors composés
de trop peu d’atomes ne sont pas suffisamment fiables.
o Dans un processus de gravure en 22 nm (nanomètre = 10-9 m), un transistor est
composé de seulement 42 atomes.
• Les limites atomiques seront bientôt atteintes :
o Taille d’un atome de silicium (Si) : rayon de van der Waals = 210 pm = 0,21 nm
(pm = picomètre = 10-12 m).
o Finesses de gravures actuelles : 10 nm (puces pour mobiles), 7 nm.
o Perspectives : 5 nm vers 2020/2021, 1 transistor = 7 atomes !
o Limite ultime de la technologie actuelle : 3 nm vers 2021/2022.
• Une densité très forte induit des phénomènes parasites de fuite de courant.
• La quantité d’énergie dissipée devient problématique !
o Chaque fois qu’un transistor change d’état, il libère une petite quantité d’énergie.
Plus il y a de transistors par unité de surface et plus il y a d’énergie dissipée.
o L’énergie dissipée est fonction de la fréquence d’horloge (nombre de transitions par
seconde) et du carré de la tension de fonctionnement (E α V2 x F).
▪ La fréquence est plafonnée à 5 GHz.
▪ La tension peut difficilement descendre en dessous de 0,9V sans causer des
problèmes techniques (bruit thermique).

1.4.3 Quelles sont les solutions envisageables ?


• Changement radical de technologie
o Utiliser l’arséniure de gallium (GaAs) en remplacement du silicium (Si).
o Supraconducteurs.
o Composants optiques.
o Dispositifs quantiques.
• À plus court terme
o Architectures multiprocesseurs (plusieurs cœurs ou processeurs interconnectés).
o Architectures parallèles distribuées (fermes de serveurs).
o Programmation parallèle efficace.

Page 1.8 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Présentation générale d’un ordinateur

2 Présentation générale
2 d’un ordinateur

2.1 Qu’est-ce qu’un ordinateur ?


2.1.1 Définition d’un ordinateur
Si on s’en réfère à la définition du Larousse, un ordinateur est une « machine automatique de
traitement de l'information, obéissant à des programmes formés par des suites d'opérations
arithmétiques et logiques ».

Un système informatique est donc composé d’une partie matérielle (unité centrale de traitement,
mémoire, périphériques…) et d’une partie logicielle (système d’exploitation, applications…).

Un exemple bien connu d’ordinateur est l’ordinateur personnel ou PC (Personal Computer) qui
convient pour un usage domestique ou comme poste de travail dans une entreprise. En voici une
illustration :

écran

clavier souris

haut-parleurs
cd/dvd

disque dur unité centrale imprimante

carte réseau
caméra
scanner

Figure 2-1 - Exemple d'ordinateur personnel

© HELMo Campus Guillemins Page 2.1


Présentation générale d’un ordinateur Architecture des ordinateurs - Théorie

Un tel système est généralement constitué des éléments décrits ci-après. Cette liste n’est pas
exhaustive. La configuration d’un ordinateur personnel peut varier en fonction de l’utilisation
envisagée.

• L’unité centrale qui contient :


o le processeur chargé d’exécuter les programmes,
o la mémoire centrale qui contient le code des programmes à exécuter, ainsi que les
données à traiter,
o les gestionnaires d’entrées/sorties.
• Des périphériques d’entrée qui permettent d’acquérir des informations : clavier, souris, scanner,
caméra…
• Des périphériques de sortie qui permettent de restituer des informations sous diverses formes :
écran, imprimante, haut-parleurs…
• Des périphériques de stockage (mémoire secondaire) qui sont soit externes, soit internes :
o Disques durs.
o Lecteur/graveur de disques optiques (CD, DVD, BlueRay).
o Clés USB.
• Des périphériques de communication :
o Carte réseau (ethernet, bluetooth, wifi, …).
o Modem (téléphonique, ADSL, RNIS, …).

2.1.2 Toute une gamme d’ordinateurs


Le PC n’est pas le seul exemple possible d’ordinateur. L’informatique nomade est de plus en plus en
vogue ces dernières années. Le traditionnel ordinateur de bureau cède désormais sa place aux
ordinateurs portables, ultraportables, netbooks, tablettes et autres téléphones intelligents
(smartphones).

En fait, l’ordinateur est devenu omniprésent. La miniaturisation de plus en plus poussée des
microprocesseurs, l’évolution impressionnante des performances et la diminution des coûts de
fabrication font que l’ordinateur est utilisé dans des domaines très variés et sous des formes
auxquelles on ne pense pas toujours.

En simplifiant un peu, nous pouvons proposer la classification suivante.

Les ordinateurs jetables


• Il s’agit de puces très simples aux fonctionnalités limitées et le plus souvent figées, produites
en très grandes séries et coûtant généralement moins d’un EURO.
• Exemples : gadgets électroniques divers (cartes musicales), puces RFID (Radio Frequency
IDentification).

Ordinateurs embarqués (microcontrôleurs)


• Cette catégorie est probablement la plus vaste et la plus variée, même si elle ne correspond
pas directement à l’idée que l’on se fait d’un ordinateur.

Page 2.2 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Présentation générale d’un ordinateur

• Un microcontrôleur est un ordinateur programmable, mais aux fonctionnalités limitées. Son


prix de revient est de quelques EUROS. Il est inclus dans un autre appareil dans le but de
piloter celui-ci et le plus souvent aussi d’assurer l’interface avec l’utilisateur. Un même
appareil peut contenir plusieurs microcontrôleurs réalisant chacun une tâche bien précise
(exemple : voiture -> freinage, climatisation, etc.).
• Electroménagers (réveil, four micro-ondes, lave-vaisselle…).
• Appareils électroniques divers (lecteur MP3, GSM, TV, appareil photo, photocopieur…).
• Périphériques d’ordinateurs (imprimante, scanner, lecteur CD/DVD, …).
• Appareils médicaux (imagerie médicale, pace maker, tensiomètre…).
• Jeux et jouets.
• Et encore bien d’autres domaines : armement, distributeurs…

Téléphones intelligents (smartphones) et consoles de jeux


• Cette catégorie correspond au concept plus traditionnel de l’ordinateur. Elle se distingue
néanmoins par le fait qu’un tel ordinateur n’est pas destiné à un usage généraliste. L’accent
est mis sur une fonctionnalité bien précise, telle que le jeu, qui va déterminer le choix des
composants utilisés. L’objectif est généralement d’obtenir le meilleur rapport qualité/prix
pour l’usage considéré. Une autre différence est que ces systèmes ne sont pas prévus pour
être évolutifs. La gamme de prix est de quelques dizaines à quelques centaines d’EURO.
• Cette catégorie tend à évoluer en puissance et en évolutivité, ce qui la rapproche de plus en
plus d’un ordinateur personnel.
• Nintendo-DS, PlayStation 3 / 4, X-Box, iPhone, Samsung Galaxy, …

Ordinateurs personnels
• C’est l’ordinateur « traditionnel » tel que nous l’avons décrit ci-dessus avec ses variantes
nomades : portable, ultraportable, netbook, tablette.
• Le prix varie de quelques centaines à quelques milliers d’EUROS.
• Il est utilisé par un seul utilisateur à la fois.

Serveurs
• Un serveur est fondamentalement une version « gonflée » d’un ordinateur personnel. Il est
destiné à être connecté au réseau afin de fournir divers services à des utilisateurs distants :
stockage de fichiers, impression, base de données, serveur Web, calcul.
• Un serveur aura généralement plus d’espace disque, plus de mémoire, plus de processeurs et
une connexion réseau à haut débit. Il n’aura pas nécessairement d’écran ou de clavier, sauf
lors de sa configuration. Souvent, il aura une forme spécialement adaptée à son installation
dans un rack.
• Le prix d’un serveur peut varier de quelques milliers d’EUROS à plusieurs centaines de
milliers.

Ferme de serveurs (cluster)


• Afin de fournir une grande puissance de calcul ou une grande capacité de stockage, la
technique la plus utilisée actuellement consiste à utiliser un grand nombre de serveurs
« standards » et à les connecter entre eux afin de réaliser ce que l’on appelle une « ferme »
de serveurs (cluster) ou encore un centre de données (data center).
• Les serveurs sont connectés entre eux par un réseau ultrarapide (plusieurs Gbits/s).

© HELMo Campus Guillemins Page 2.3


Présentation générale d’un ordinateur Architecture des ordinateurs - Théorie

• Un logiciel spécifique est conçu pour répartir la charge de traitement sur les différentes
machines, ce qui permet de traiter simultanément un très grand nombre de requêtes.
Exemples : services Internet (Google, Amazon, …).
• Une autre utilisation d’une ferme de serveur est de faire collaborer un très grand nombre de
serveurs à la résolution d’un problème unique.
Exemples : simulations numériques, modèles météorologiques, …

Superordinateurs, mainframes
• L’âge d’or des superordinateurs (Cray, Connection Machine, …) aux architectures très
spécifiques est révolu. Les nouveaux « superordinateurs » sont désormais construits sur base
de fermes de serveurs standards qui parviennent à délivrer autant de puissance de calcul que
des superordinateurs à architectures spécifiques, et cela à un prix nettement inférieur.
• Reliques du passé, certains mainframes (successeurs de l’IBM 360) sont encore maintenus en
activité de nos jours, par exemple dans le secteur bancaire. Ceci est dû à l’énorme
investissement qui a été consenti pour mettre ces systèmes en place (logiciels, données,
procédures…) et aux coûts et risques qu’une migration complète et rapide engendrerait.

2.1.3 L’informatique dans les nuages : le mainframe


réinventé !
La mode actuelle est au « cloud », c’est-à-dire littéralement « nuage ». On peut donc traduire « cloud
computing » par « informatique dans les nuages », ou plus exactement « traitements distribués sur
Internet ».

2.1.3.1 Définition
Un « cloud » n’est rien d’autre qu’une ou plusieurs fermes de serveurs qui fournissent des services
aux utilisateurs connectés à travers Internet.

D’une certaine manière, le « cloud » réinvente le concept de mainframe sur base des technologies
actuelles :
• la ferme de serveur remplace le mainframe,
• l’ordinateur personnel ou le smartphone remplace le terminal,
• Internet remplace la liaison téléphonique par modem.

2.1.3.2 Intérêt
Le fait d’offrir des services sous forme de « cloud » permet de réaliser plusieurs objectifs :
• mutualiser les ressources pour fournir à moindre coût un service à un très grand nombre
d’utilisateurs ;
• la connexion via Internet permet de rendre le service accessible de n’importe où (ou
presque) ;
• le stockage des données dans le « cloud » permet d’offrir de nouveaux services, tels que la
synchronisation de plusieurs appareils, le partage de documents, la gestion collaborative de
documents.
Il convient de noter que toutes ces fonctionnalités sont déjà mises en œuvre au sein d’un réseau
privé ou d’une d’entreprise. Le « cloud » élargit seulement l’horizon à Internet.

Page 2.4 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Présentation générale d’un ordinateur

2.1.3.3 Services « cloud » proposés aux entreprises

IaaS – Infrastructure as a Service – Infrastructure en tant que service

L’idée est de louer à une entreprise l’infrastructure matérielle dont elle a besoin (connectivité réseau,
serveurs, stockage), celle-ci étant délocalisée dans le cloud.

Le fournisseur de service est responsable de la fourniture, de l’installation, de la configuration de


base et de la maintenance du matériel. L’entreprise est responsable de la partie applicative et peut
utiliser l’infrastructure mise à sa disposition comme elle le souhaite (système d’exploitation,
applications diverses). L’offre « IaaS » permet également une grande flexibilité aux entreprises qui
peuvent adapter de manière dynamique leur parc de serveurs en fonction de leurs besoins.

PaaS – Platform as a Service – Plateforme en tant que service

Le service fourni aux entreprises dans le modèle « PaaS » inclut non seulement l’infrastructure, mais
également le système d’exploitation et les logiciels de base (base de données, serveur Web, outils de
développement, …) qui permettent à l’entreprise de développer et de déployer rapidement ses
propres applications.

SaaS – Software as a Service – Logiciel en tant que service

Dans ce dernier modèle, le gestionnaire du cloud fournit un service applicatif à ses clients et est
responsable de l’intégralité de la solution (connectivité, matériel, logiciel). Le client final peut
uniquement paramétrer la solution offerte pour l’adapter à ses besoins. Cette approche permet à
une entreprise de déployer des applications ou services ambitieux sur Internet avec une équipe
technique très réduite, sans avoir à se préoccuper de la gestion opérationnelle d’une infrastructure
complexe. Exemples de solutions « SaaS » : site de vente en ligne, gestion de personnel,
vidéoconférence…

Données Données Données

Applications Applications Applications

Logiciels de base Logiciels de base Logiciels de base

Système (OS) Système (OS) Système (OS)

Virtualisation Virtualisation Virtualisation

Serveur + stockage Serveur + stockage Serveur + stockage

Réseau Réseau Réseau

IaaS PaaS SaaS

Figure 2-2 - Les différentes offres de services cloud

Si l’émergence des services « cloud » offre de nouvelles possibilités et une plus grande flexibilité aux
entreprises, la mise en œuvre de ces services pose néanmoins quelques questions importantes :
• Sécurité et confidentialité des données stockées dans le « cloud » ?
• Disponibilité de l’accès à Internet ?
• Disponibilité du service (Service Level Agreement – SLA) ?
• Dépendance forte à l’égard d’un fournisseur : changement de fournisseur ?

© HELMo Campus Guillemins Page 2.5


Présentation générale d’un ordinateur Architecture des ordinateurs - Théorie

2.2 Organisation interne d’un ordinateur


monoprocesseur
2.2.1 Organisation de base
Comme nous l’avons expliqué au chapitre 1, la structure interne de la plupart des ordinateurs
monoprocesseurs modernes suit le principe d’organisation de la machine de Von Neumann.

Unité centrale de traitement (CPU)

Unité de
contrôle

Unité
arithmétique
et logique
Périphériques d’entrée/sortie
Registres

Mémoire
Disque Imprimante
centrale

Bus d’interconnexion

Figure 2-3 - Organisation de base d'un ordinateur

On y retrouve les éléments principaux identifiés par Von Neumann, à savoir :

• L’unité centrale de traitement (CPU) qui contient :


o l’unité de contrôle,
o l’unité arithmétique et logique (ALU),
o un ensemble de registres (cellules mémoire à accès très rapides utilisées par l’ALU).
• La mémoire centrale.
• Les périphériques d’entrées et sorties.

Une évolution majeure par rapport à l’architecture de Von Neumann, qui est apparue pour la
première fois avec le DEC/PDP-8, est l’introduction d’un bus de communication (ensemble de fils
parallèles) utilisé pour interconnecter les différents composants de l’ordinateur.

2.2.2 L’unité centrale de traitement


L’unité centrale de traitement (CPU) est le centre névralgique de l’ordinateur. C’est elle qui exécute
les instructions d’un programme.

Le programme à exécuter et ses données sont tout d’abord chargés en mémoire centrale. On peut
ensuite schématiser l’exécution d’un programme par la répétition de la séquence d’opérations
suivante, que l’on appelle un cycle d’exécution :

Page 2.6 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Présentation générale d’un ordinateur

1. Lire une instruction en mémoire.


2. Décoder cette instruction pour déterminer l’opération à réaliser.
3. Obtenir les données utilisées pour cette opération.
4. Réaliser le traitement approprié au moyen de l’ALU.
5. Sauvegarder le résultat éventuel.
6. Passer à l’instruction suivante.

C’est le rôle de l’unité de contrôle (ou de commande) d’assurer le séquencement des opérations au
sein du CPU. L’unité arithmétique et logique (ALU) réalise quant à elle les opérations arithmétiques et
logiques demandées par le programme.

Les données utilisées par l’ALU peuvent se trouver dans les registres du processeur ou en mémoire
centrale. Certaines architectures de processeurs imposent que toutes les données manipulées par
l’ALU se trouvent dans les registres (à l’exception bien sûr des opérations de transfert entre un
registre et la mémoire centrale).

 L’organisation interne et le fonctionnement du CPU sont détaillés au chapitre 5.

2.2.3 La mémoire centrale


Elle contient les instructions du programme, ainsi que les données manipulées. En mémoire, rien ne
permet de distinguer une instruction d’une donnée. Toutes deux sont codées par une succession de
bits 0 ou 1.

Le temps nécessaire pour accéder à (ou écrire) une donnée en mémoire centrale est très long par
rapport au temps nécessaire à l’exécution d’une instruction par l’ALU (10 à 50x). C’est pourquoi on
essaiera d’utiliser au maximum les registres du processeur, par exemple pour stocker les résultats
intermédiaires d’un calcul. Pour réduire l’impact négatif des longs temps d’accès à la mémoire
centrale, on utilise aussi une mémoire intermédiaire plus petite, mais beaucoup plus rapide, appelée
mémoire cache (ou antémémoire).

 Nous décrirons le fonctionnement de la mémoire centrale au chapitre 6.

2.2.4 Les entrées et sorties


Lors de l’exécution d’un programme, le CPU peut faire appel à un périphérique d’entrées/sorties
pour communiquer avec le monde extérieur. La vitesse de transfert de données entre le CPU et les
périphériques d’entrées/sorties est encore nettement plus faible qu’entre le CPU et la mémoire
centrale. C’est pourquoi le CPU ne pilote pas directement un périphérique. Il s’adresse à un
contrôleur spécialisé connecté sur le bus, auquel il délègue la tâche de piloter le périphérique.

Dans les architectures modernes, un ordinateur contiendra en général au moins deux bus : un bus
système qui fournit au CPU un accès très rapide à la mémoire et un bus d’entrées/sorties servant à
connecter les contrôleurs d’entrées/sorties.

 Nous reviendrons en détail sur les mécanismes d’entrées/sorties au chapitre 7.

© HELMo Campus Guillemins Page 2.7


Présentation générale d’un ordinateur Architecture des ordinateurs - Théorie

2.2.5 Organisation améliorée


La figure suivante présente une version améliorée de la structure interne d’un ordinateur
monoprocesseur. Cette organisation intègre une mémoire cache, ainsi que deux bus de
communication.

Bus système

Mémoire Mémoire
CPU
cache centrale

Bus d’entrée/sortie

Disque Imprimante

Périphériques d’entrée/sortie

Figure 2-4 - Organisation améliorée d'un ordinateur

2.3 Architecture en couches


Afin de réduire la complexité de mise en œuvre d’un système informatique, l’architecture interne de
tous les ordinateurs modernes est structurée en une série de couches « empilées ». Chaque couche
fournit un certain nombre de services qui sont utilisés par la couche supérieure.

Niveau 5 – Langage de haut-niveau


Compilation
Niveau 4 – Langage d’assemblage
Assembleur
Niveau 3 – Système d’exploitation
Langage machine/interprétation
Niveau 2 – Jeu d’instructions
Exécution directe / microprogrammation
Niveau 1 – Microarchitecture
Matériel (carte mère)
Niveau 0 – Electronique digitale

Figure 2-5 - Structure en couches d'un ordinateur

Page 2.8 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Présentation générale d’un ordinateur

Niveau 0 – Électronique digitale


• C’est le niveau le plus bas de l’ordinateur. Il se compose des éléments électroniques de base
(portes logiques, bascules, horloges…) servant à réaliser des opérations logiques
élémentaires, construire des registres, des mémoires, une unité arithmétique et logique, etc.

 Nous nous intéressons à ce niveau dans le chapitre 4.

Niveau 1 – Microarchitecture
• La microarchitecture consiste à connecter et à organiser les éléments de base.

• Les registres et l’ALU sont regroupés au sein du CPU. Une unité de contrôle est créée afin
d’organiser le séquencement des opérations dans le CPU. Suivant les machines, l’unité de
contrôle est réalisée au moyen d’une logique câblée ou d’un microprogramme.

• La microarchitecture comprend également la mémoire centrale, la mémoire cache, les bus


de communication. C’est-à-dire tous les éléments matériels qui définissent les
fonctionnalités offertes aux couches supérieures.

 Nous nous intéressons à ce niveau dans le chapitre 5.

Niveau 2 – Architecture de jeu d'instructions (ISA – Instruction Set


Architecture)
• Le jeu d’instructions de base d’un ordinateur est la spécification formelle des instructions-
machine offertes par les niveaux 0 et 1. Il décrit donc toutes les instructions que la
microarchitecture est capable d’exécuter, soit par microprogramme, soit par logique câblée.

• Le code machine est le seul langage de programmation directement compréhensible par


l’ordinateur. En pratique, il n’est quasiment jamais utilisé directement, car la manipulation
directe d’un code binaire est peu commode et on préférera utiliser un langage symbolique de
bas niveau (langage d’assemblage) ou un langage de haut niveau (C, Java, Perl, etc.).

 Nous nous intéressons à ce niveau dans le chapitre 5.

Niveau 3 – Système d’exploitation


• Le système d’exploitation dont nous parlons ici est un programme en code machine, ou
interprété par le microprogramme du niveau 2. Il est responsable de la gestion de bas niveau
des ressources matérielles de l’ordinateur.

• Le système d’exploitation peut également enrichir le jeu d’instructions de base avec de


nouvelles instructions qui seront interprétées par le microprogramme du niveau 2.

• Une partie du système d’exploitation est stockée au sein de l’ordinateur, dans une mémoire
permanente : c’est le micrologiciel (firmware). Le firmware est exécuté de manière
automatique au démarrage de la machine. Il contient le code permettant la gestion des
fonctions de base : démarrage d’autres processus, gestion de la mémoire, opérations de base

© HELMo Campus Guillemins Page 2.9


Présentation générale d’un ordinateur Architecture des ordinateurs - Théorie

pour les entrées/sorties…. Sa première tâche est de charger en mémoire le reste du système
d’exploitation qui est stocké dans une mémoire secondaire (disque dur ou SSD, DVD, clé
USB…).

• Les systèmes d’exploitation « commerciaux » de type Windows, UNIX sont en fait constitués
d’une multitude de programmes qui vont bien au-delà de la simple gestion du système.
Néanmoins, ils contiennent tous au minimum un noyau (kernel) qui fournit les
fonctionnalités de base évoquées ci-devant.

• Le niveau 3 constitue la frontière entre la partie système et la partie utilisateur de


l’ordinateur. Les couches inférieures sont réservées à des programmeurs spécialisés
(programmeurs système). Ces couches ont pour but d’offrir les services de plus haut niveau
(interpréteur, compilateur, chargeur, abstraction des entrées/sorties) utiles aux
programmeurs de logiciels applicatifs.

 Nous nous intéressons au système d’exploitation dans le chapitre 8.

Niveau 4 – Langage d’assemblage


• Le langage d’assemblage (ou assembleur) est une représentation symbolique du code
machine. Cette représentation est nettement plus facile à utiliser par l’être humain. En effet,
si on souhaite additionner 2 nombres, il est plus commode d’écrire « add 7, 3 » que
« 1000110010100000 ».

• Un programme écrit en langage d’assemblage ne peut pas être exécuté directement par le
processeur. Le code symbolique doit d’abord être traduit en code machine. Le programme
qui réalise cette traduction s’appelle un assembleur.

• En plus du jeu d’instructions du processeur, le langage d’assemblage peut offrir des


fonctionnalités supplémentaires : pseudo-instructions, macros, symboles…

• Le langage d’assemblage est essentiellement utilisé par les programmeurs système pour
écrire des programmes pour les niveaux 2 et 3.

 Nous parlerons brièvement du langage d’assemblage dans le chapitre 5.

Niveau 5 – Langages de haut-niveau


• Les langages de haut niveau tels que C, C#, Java, PHP… sont utilisés par les programmeurs
d’applications, dans le but de résoudre un problème déterminé. Ces langages proposent des
constructions plus évoluées et une facilité d’utilisation plus grande que l’assembleur.

• Il existe deux techniques principales pour exécuter un programme écrit dans un langage de
haut niveau : la compilation et l’interprétation.

o La compilation consiste à traduire un programme écrit dans un langage de haut


niveau vers un programme équivalent en code machine. La compilation s’effectue
avant l’exécution du programme. Le logiciel chargé de cette traduction s’appelle un
compilateur. Il traduit le programme de départ soit directement en code machine,

Page 2.10 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Présentation générale d’un ordinateur

soit en un programme en langage d’assemblage qui sera à son tour traduit en code
machine par un assembleur. Le langage C est un bon exemple de langage compilé.

o L’interprétation d’un langage de haut niveau consiste à utiliser un logiciel spécial,


appelé interpréteur, qui va analyser, traduire et exécuter au fur et à mesure les
instructions du programme. L’interprétation du programme est donc réalisée à
chaque exécution de celui-ci, contrairement à la compilation qui est réalisée une fois
pour toutes. Les langages PHP et Perl sont des langages interprétés.

• Le langage Java offre une approche hybride entre la compilation et l’interprétation. En effet,
le code source Java est compilé vers un jeu d’instructions intermédiaire appelé « Java Byte
Code » (code machine Java). Ce jeu d’instructions correspond donc à l’architecture de niveau
2 (ISA) d’un processeur qui serait capable d’exécuter du code machine Java. Un certain
nombre de processeurs Java ont été construits, mais ils restent cantonnés à des projets de
recherche. En pratique, le code machine Java est exécuté par une machine virtuelle Java
(Java Virtual Machine – JVM), c’est-à-dire un interpréteur qui simule un processeur Java en
traduisant à la volée le code machine Java vers le code machine du processeur hôte. Un
programme en code machine Java peut donc être exécuté sur n’importe quel processeur, à
condition de disposer de la machine virtuelle Java correspondante.

2.4 Architectures CISC et RISC


Le jeu d’instructions offert par un processeur peut être plus ou moins riche suivant le processeur. Il
résulte d’un compromis entre deux objectifs de conception contradictoires :

• Faciliter la vie du programmeur en lui offrant le jeu d’instructions le plus riche possible.
• Garder une architecture matérielle simple et efficace.

Historiquement, la tendance a été d’ajouter de plus en plus d’instructions au jeu d’instructions d’un
processeur. Ainsi, dans la famille des processeurs Intel x86, les générations successives ont apporté :

• Des instructions de tailles variables.


• Adressage sur 8, 16, 24, 32 et 64 bits.
• De très nombreux mode d’adressage (c.-à-d. manières d’accéder à une cellule mémoire).
• Intel 8087 : 60 instructions de calcul en virgule flottante.
• Pentium II : 57 instructions MMX (MultiMedia eXtension) pour accélérer les traitements
audio et vidéo.
• Pentium III : 70 instructions SSE (Streaming SIMD Extensions) pour accélérer les graphismes
en 3D.
• 144 instructions SSE2, 13 instructions SSE3, 54 instructions SSE4, 170 instructions SSE5, 128
instructions AVE (Advanced Vector Extension), …

En fin de compte, l’architecture Intel offre un nombre d’instructions très impressionnant !

Ce type d’architecture est appelée architecture CISC (Complex Instruction Set Computer), c’est-à-dire
« ordinateur à jeu d’instructions complexe ». Exemples : processeurs Intel x86, Motorola 680x0.

© HELMo Campus Guillemins Page 2.11


Présentation générale d’un ordinateur Architecture des ordinateurs - Théorie

Les instructions sophistiquées d’un processeur CISC sont très commodes à utiliser, mais :

• La mise en œuvre de ces instructions rend le processeur extrêmement complexe.


• La complexité du processeur ralentit l’exécution des instructions simples.
• De nombreux logiciels ne sont pas optimisés pour tirer parti de ces instructions avancées.
• Les progrès réalisés au niveau des compilateurs permettent maintenant de traduire
efficacement les instructions d’un langage de haut niveau vers des instructions-machine
simples.

La complexité croissante de mise en œuvre des processeurs CISC a amené certains concepteurs de
processeurs à changer complètement l’angle d’approche et à proposer une architecture alternative
appelée RISC (Reduced Instruction Set Computer), c’est-à-dire « ordinateur à jeu d’instructions
réduit». Exemples : PowerPC, ARM, MIPS.

Comme son nom l’indique, une architecture RISC propose un jeu d’instructions limité à un petit
nombre d’opérations simples. Ces instructions ont une taille fixe et le nombre de modes d’adressage
est limité. La mise en œuvre des instructions au niveau matériel est grandement facilitée, ce qui
permet une exécution très rapide. L’unité de contrôle sera généralement câblée. Dans une
architecture RISC, le rôle du compilateur est essentiel. Il doit être capable de produire un code
efficace, qui exploite au maximum les caractéristiques de la machine.

Durant de nombreuses années, l’opposition CISC/RISC a fait rage. Actuellement, on observe une
« fusion » des deux approches. Les processeurs Intel des dernières générations sont en effet basés
sur une architecture de type RISC. La compatibilité avec l’ensemble des instructions complexes x86
est assurée grâce à un microprogramme qui traduit les instructions complexes en une série
d’instructions simples. De leur côté, les processeurs RISC gagnent progressivement en complexité.
C’est ainsi que le jeu d’instructions des processeurs ARM contient maintenant des instructions pour
les calculs en virgule flottante ou vectoriels.

Page 2.12 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Le codage des informations

3 Le codage des
3 informations

3.1 Systèmes de numération


3.1.1 Systèmes de numération utilisés en informatique
Nous avons introduit au chapitre 1 la notion de numération positionnelle et base de numération. Les
systèmes de numération les plus utilisés en informatique sont repris dans le tableau suivant.

Système Base Symboles


Décimal 10 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
Binaire 2 0, 1
Octal 8 0, 1, 2, 3, 4, 5, 6, 7
Hexadécimal 16 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F

Figure 3-1 - Principaux systèmes de numération en informatique

Le système décimal est celui que nous utilisons le plus couramment dans la vie de tous les jours. Il
utilise les chiffres de 0 à 9. Ce système n’est toutefois pas le plus adapté aux traitements par un
ordinateur.

Le choix le plus approprié pour représenter des informations dans un ordinateur c’est le binaire. Le
système binaire utilise uniquement deux symboles (0 et 1), ce qui correspond naturellement au
comportement des composants électroniques. Ceux-ci manipulent également deux valeurs
distinctes : présence ou absence de courant (ou de tension).

Les systèmes octal et hexadécimal permettent une représentation plus commode et surtout plus
compacte des données, tout en offrant une conversion aisée depuis et vers le système binaire
comme nous l’expliquerons à la section 3.2.3.

Le système hexadécimal comportant 16 symboles, il est nécessaire d’ajouter 6 symboles en plus des
chiffres 0 à 9. Il s’agit des lettres A, B, C, D, E et F, qui représentent respectivement les valeurs 10, 11,
12, 13, 14 et 15.

L’hexadécimal est fréquemment utilisé en informatique. Il sert par exemple à exprimer une nuance
de couleur lors du développement de pages Web (#FFA500 = orange) ; à représenter la valeur d’une
empreinte cryptographique MD5 ("test MD5" → 212A4C389DB4ECFACF61817A711CF892), etc.

Le tableau qui suit donne la valeur des nombres décimaux de 0 à 15 en binaire, octal et hexadécimal.

© HELMo Campus Guillemins Page 3.1


Le codage des informations Architecture des ordinateurs - Théorie

Décimal Binaire Octal Hexadécimal


0 0000 00 0
1 0001 01 1
2 0010 02 2
3 0011 03 3
4 0100 04 4
5 0101 05 5
6 0110 06 6
7 0111 07 7
8 1000 10 8
9 1001 11 9
10 1010 12 A
11 1011 13 B
12 1100 14 C
13 1101 15 D
14 1110 16 E
15 1111 17 F
Figure 3-2 - Table de conversion décimal/binaire/octal/hexadécimal

3.1.2 Formule générale de définition d’un nombre entier


Rappelons que dans un système de numération positionnelle, la valeur attribuée à un chiffre dans la
représentation d’un nombre dépend de la position du chiffre et de la base de numération utilisée.

Si nous connaissons la base utilisée par un système de numération, nous pouvons définir de manière
générale un nombre entier N exprimé en base B de la manière suivante :

NB = an Bn + an-1 Bn-1 + … + a2 B2 + a1 B1 + a0 B0 = ∑𝑛𝑖=0 ⁡𝑎𝑖 𝐵𝑖 Forme expansée


NB = anan-1 … a2a1a0 (ex.: 1234) Forme normale

Où ai est un des symboles de la base B.

Exemples

123410 = 1x103 + 2x102 + 3x101 + 4x100 Base 10, symboles : 0, 1, 2, 3, 4, 5, 6, 7, 8, 9


12348 = 1x83 + 2x82 + 3x81 + 4x80 = 66810 Base 8, symboles : 0, 1, 2, 3, 4, 5, 6, 7

L’indice mentionné juste après un nombre indique la base de numération utilisée (123410 → décimal,
12348 → octal). Si la base n’est pas mentionnée de manière explicite, on considérera généralement
qu’il s’agit de la base 10, sauf si le contexte permet de connaître la base utilisée.

3.1.3 Formule générale de définition d’un nombre réel


La formule générale de définition d’un nombre réel N exprimé en base B est une simple extension de
celle utilisée pour un nombre entier. Les chiffres après la virgule correspondent simplement à des
puissances négatives de la base. On obtient donc :

NB = an Bn + an-1 Bn-1 + … + a0 B0 + a-1 B-1 + … + a-m B-m = ∑𝑛𝑖=−𝑚 ⁡𝑎𝑖 𝐵𝑖 Forme expansée
NB = anan-1 … a2a1a0 , a-1 … a-m (ex: 1234,56) Forme normale

Où ai est un des symboles de la base B.

Page 3.2 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Le codage des informations

Exemples

1234,5610 = 1x103 + 2x102 + 3x101 + 4x100 + 5x10-1 + 6x10-2


1234,568 = 1x83 + 2x82 + 3x81 + 4x80 + 5x8-1 + 6x8-2 = 668,7187510

3.1.4 Opérations arithmétiques


3.1.4.1 Addition et multiplication en décimal (base 10)
En arithmétique décimale, il est très facile de réaliser l’addition de 2 nombres, quelle que soit la
longueur de ces nombres. En effet, il suffit d’appliquer une procédure qui revient essentiellement à
additionner de manière répétée 2 nombres constitués d’un seul chiffre. Pour y parvenir, nous avons
dû mémoriser à l’école primaire la table d’addition suivante :

+ 0 1 2 3 4 5 6 7 8 9
0 0 1 2 3 4 5 6 7 8 9
1 1 2 3 4 5 6 7 8 9 10
2 2 3 4 5 6 7 8 9 10 11
3 3 4 5 6 7 8 9 10 11 12
4 4 5 6 7 8 9 10 11 12 13
5 5 6 7 8 9 10 11 12 13 14
6 6 7 8 9 10 11 12 13 14 15
7 7 8 9 10 11 12 13 14 15 16
8 8 9 10 11 12 13 14 15 16 17
9 9 10 11 12 13 14 15 16 17 18
Figure 3-3 - Table d’addition en décimal

Pour calculer la somme de deux nombres d’un chiffre, il suffit de regarder dans la table d’addition la
valeur qui est indiquée dans la case située à l’intersection de la ligne et de la colonne qui
correspondent aux 2 nombres à additionner. Par exemple, on trouve que 6 + 8 = 14.

Pour additionner 2 nombres de tailles plus grandes, on commence par placer les 2 nombres l’un en
dessous de l’autre en alignant les chiffres des positions correspondantes. Ensuite, en procédant de la
droite vers la gauche, on additionne tous les chiffres d’une même colonne, on inscrit le chiffre des
unités du total comme chiffre de résultat et on reporte une retenue de 1 dans la colonne de gauche
suivante si ce total atteint 10 ou plus. Et ainsi de suite…

Exemple : 23749,17 + 4974,03 = 28723,20

111 1 ← retenues reportées


23749,17
+ 4974,03
28723,20

© HELMo Campus Guillemins Page 3.3


Le codage des informations Architecture des ordinateurs - Théorie

Pour réaliser une multiplication à la main, la procédure est un peu plus complexe, mais en définitive
les étapes à réaliser consistent également à additionner ou à multiplier des nombres décimaux d’un
seul chiffre. À cette fin, nous avons également dû mémoriser la table de multiplication suivante :

x 0 1 2 3 4 5 6 7 8 9
0 0 0 0 0 0 0 0 0 0 0
1 0 1 2 3 4 5 6 7 8 9
2 0 2 4 6 8 10 12 14 16 18
3 0 3 6 9 12 15 18 21 24 27
4 0 4 8 12 16 20 24 28 32 36
5 0 5 10 15 20 25 30 35 40 45
6 0 6 12 18 24 30 36 42 48 54
7 0 7 14 21 28 35 42 49 56 63
8 0 8 16 24 32 40 48 56 64 72
9 0 9 18 27 36 45 54 63 72 81
Figure 3-4 - Table de multiplication en décimal

Exemple : 23476,2 x 2130,4 = 50013696,48

2 3 4 7 6 , 2
x 2 1 3 0 , 4
9 3 9 0 4 8 ← 4 x 234762 [4x2=8, 4x6=24, 4x7+2=30, …]
0 0 0 0 0 0 ← 0 x 234762
7 0 4 2 8 6 ← 3 x 234762
2 3 4 7 6 2 ← 1 x 234762
4 6 9 5 2 4-------- ← 2 x 234762
5 0 0 1 3 6 9 6,4 8

3.1.4.2 Addition et multiplication en base quelconque


La beauté du système de numération positionnelle est que la manière de réaliser les opérations
arithmétiques est identique quelle que soit la base. Il suffit d’utiliser les tables d’addition et de
multiplication correspondantes. Ainsi, en octal (base 8), on utilisera :

+ 0 1 2 3 4 5 6 7 x 0 1 2 3 4 5 6 7
0 0 1 2 3 4 5 6 7 0 0 0 0 0 0 0 0 0
1 1 2 3 4 5 6 7 10 1 0 1 2 3 4 5 6 7
2 2 3 4 5 6 7 10 11 2 0 2 4 6 10 12 14 16
3 3 4 5 6 7 10 11 12 3 0 3 6 11 14 17 22 25
4 4 5 6 7 10 11 12 13 4 0 4 10 14 20 24 30 34
5 5 6 7 10 11 12 13 14 5 0 5 12 17 24 31 36 43
6 6 7 10 11 12 13 14 15 6 0 6 14 22 30 36 44 52
7 7 10 11 12 13 14 15 16 7 0 7 16 25 34 43 52 61
Figure 3-5 - Tables d’addition et de multiplication en octal

Page 3.4 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Le codage des informations

Exemples en octal : 423,178 + 1246,038 = 1671,228 1238 x 4568 = 607528

1 1 ← reports 123
423,17 x 456
+ 1246,03 762 ← 6 x 123 [6x3=22, 6x2+2=16, 6x1+1=7]
1671,22 637
514 —
60752

Le cas de l’arithmétique binaire est particulièrement simple, puisqu’en base 2 les tables d’addition et
de multiplication se réduisent à seulement 4 cases. Voilà qui nous aurait fortement simplifié la tâche
à l’école primaire !

+ 0 1 x 0 1
0 0 1 0 0 0
1 1 10 1 0 1
Figure 3-6 - Tables d’addition et de multiplication en binaire

Exemples en binaire :

1101011,0112 + 101110,112 = 10011010,0012 (107,37510 + 46,7510 = 154,12510)


101101,0112 x 11010,12 = 10010110010,01112 (45,37510 x 26,510 = 1202,437510)

11 11111 1 ← reports 1 0 1 1 0 1,0 1 1


1101011,011 x 1 1 0 1 0,1 - -
+ 101110,11 1 0 1 1 0 1 0 1 1
10011010,001 1 0 1 1 0 1 0 1 1
1 0 1 1 0 1 0 1 1
1 0 1 1 0 1 0 1 1 —
1 0 0 1 0 1 1 0 0 1 0,0 1 1 1

3.1.5 Similitudes entre bases


Nous avons vu dans la section précédente que si on utilise un système de numération positionnelle,
les opérations arithmétiques fonctionnent d’une manière similaire dans les différentes bases.
D’autres comportements auxquels nous sommes habitués en décimal restent valables dans d’autres
bases. Nous les illustrons pour la base 2 (binaire), car nous l’utiliserons intensivement dans la suite
du cours.

• Ajouter des zéros à gauche de la partie entière ou à droite de la partie fractionnaire d’un
nombre ne change pas sa valeur. L’inverse n’est pas vrai.

Décimal 123,456 = 00123,45600 123,456 ≠ 12300,00456


Binaire 101,111 = 00101,11100 101,111 ≠ 10100,00111

© HELMo Campus Guillemins Page 3.5


Le codage des informations Architecture des ordinateurs - Théorie

• Décaler la représentation d’un nombre d’une position vers la gauche revient à le multiplier
par la valeur de la base.

Décimal 1,23 12,3 (x10) 123,0 (x100) 1230,0 (x1000)


Binaire 1,11 11,1 (x2) 111,0 (x4) 1110,0 (x8)
1,7510 3,510 710 1410

• Décaler la représentation du nombre d’une position vers la droite revient à le diviser par la
valeur de la base.

Décimal 1230,0 123,0 (/10) 12,3 (/100) 1,23 (/1000)


Binaire 1110,0 111,0 (/2) 11,1 (/4) 1,11 (/8)
1410 710 3,510 1,7510

• Il est très facile de déterminer les multiples d’une puissance positive de la base.

Les multiples de 10 (101) en base 10 se terminent par 1 zéro : 10, 130, 4560…
Les multiples de 2 (21) en base 2 aussi : 102 (210), 10102 (2010), 1101102 (10610)…

Les multiples de 1000 (103) en base 10 se terminent par 3 zéros : 2000, 54000, 1324000…
Les multiples de 8 (23) en base 2 aussi : 10002 (810), 11010002 (10410), 11011110002 (88810)…

De manière générale, les multiples de Bn en base B se terminent par n zéro.

• Déterminer le quotient et le reste de la division euclidienne par une puissance positive de la


base est une opération triviale qui consiste à découper le nombre en deux parties (Q | R).

Décimal 123456 /10 → 12345 | 6 /100 → 1234 | 56 /1000 → 123 | 456


Binaire 101101 /2 → 10110 | 1 /4 → 1011 | 01 /8 → 101 | 101

Le reste de la division euclidienne par Bn est donné par les n derniers chiffres du nombre, le
quotient par les chiffres restants.

Page 3.6 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Le codage des informations

3.2 Conversion entre bases


3.2.1 Nombres entiers : base B vers décimal
Pour obtenir la valeur décimale d’un nombre N exprimé en base B, il suffit d’appliquer la formule
générale. Voici quelques exemples.

1234 = 1x42 + 2x41 + 3x40 = 1x16 + 2x4 + 3x1 = 2710


10102 = 1x23 + 0x22 + 1x21 + 0x20 = 1x8 + 0x4 + 1x2 + 0x1 = 1010
12348 = 1x83 + 2x82 + 3x81 + 4x80 = 1x512 + 2x64 + 3x8 + 4x1 = 66810
CAFE16 = 12x163 + 10x162 + 15x161 + 14x160 = 12x4096 + 10x256 + 15x16 + 14x1 = 5196610

3.2.2 Nombres entiers : décimal vers base B


3.2.2.1 Méthode 1 – Resserrement d’intervalle
Rappelons la formule générale de définition d’un nombre entier en base B :

N = an Bn + an-1 Bn-1 + … + a2 B2 + a1 B1 + a0

La technique du resserrement d’intervalle consiste à répéter les opérations suivantes :

1. Déterminer la plus grande puissance n de B qui est strictement inférieure ou égale à N.


Bn ≤ N < Bn+1
𝑁
2. Réaliser la division entière : 𝐵𝑛
= 𝑎𝑛 → le quotient est le coefficient du terme an Bn.
3. Soustraire le terme an Bn du nombre N afin d’obtenir le reste R.

R = N - an Bn = an-1 Bn-1 + … + a2 B2 + a1 B1 + a0

4. Recommencer au point 2 avec N’ = R et la puissance n-1 de la base, jusqu’à la puissance 0.

Exemple 1 : convertir le nombre 259810 en octal (base 8)

Les puissances successives de 8 sont : 80=1, 81=8, 82=64, 83=512, 84=4096, etc. On obtient la séquence
de resserrement d’intervalle suivante :

• 83 (512) ≤ 2598 < 84 (4096) → Q = 2598/512 = 5 a3 R = 2598 - 5x512 = 38


• 82 (64) → Q = 38/64 = 0 a2 R = 38
• 81 (8) → Q = 38/8 = 4 a1 R = 38 - 4x8 = 6
• 80 (1) → Q = 6/1 = 6 a0 R = 6 - 6x1 = 0

Le résultat est donc : 259810 = 50468.

Dans la technique du resserrement d’intervalle, chaque quotient successif est un chiffre du résultat
final, sa valeur est donc obligatoirement comprise entre 0 et B-1.

© HELMo Campus Guillemins Page 3.7


Le codage des informations Architecture des ordinateurs - Théorie

Exemple 2 : convertir le nombre 22110 en binaire (base 2)

Les puissances de 2 sont : 20=1, 21=2, 22=4, 23=8, 24=16, 25=32, 26=64, 27=128, 28=256, etc.

La technique du resserrement d’intervalle est simplifiée lors d’une conversion en binaire par le fait
que le quotient de la division est obligatoirement 0 ou 1 selon que la puissance de 2 considérée et
supérieure ou non au nombre restant. En pratique, il suffit donc de soustraire des puissances de 2 du
nombre de départ jusqu’à obtenir un reste égal à 0.

• 27 (128) → Q=1 a7 R = 221 - 128 = 93


• 26 (64) → Q=1 a6 R = 93 - 64 = 29
• 25 (32) → Q=0 a5 R = 29
• 24 (16) → Q=1 a4 R = 29 - 16 = 13
• 23 (8) → Q=1 a3 R = 13 - 8 = 5
• 22 (4) → Q=1 a2 R=5-4=1
• 21 (2) → Q=0 a1 R=1
• 20 (1) → Q=1 a0 R = 1 - 1 =0

Le résultat est donc : 22110 = 110111012.

3.2.2.2 Méthode 2 – Division par la base


Rappelons tout d’abord la formule du quotient :
Dividende = Quotient x Diviseur + Reste → N = Q x B + R
Or, on peut réécrire la formule générale de représentation d’un nombre comme suit :

N = ( an Bn-1 + an-1 Bn-2 + … + a2 B1 + a1 ) x B + a0 qui est de la forme N = Q x B + R

où R = a0 et
Q = an Bn-1 + an-1 Bn-2 + … + a2 B1 + a1 = N’ = ( an Bn-2 + an-1 Bn-3 + … + a2 ) x B + a1

Le coefficient a0 est donc le reste de la division entière de N par B.

Si on appelle N’ le quotient de la division entière de N par B, le coefficient a1 est à son tour le reste
de la division entière de N’ par la base. On recommence cette opération tant que le quotient obtenu
est différent de 0.

Exemple 1 : convertir le nombre 259810 en octal (base 8)

• 2598 / 8 → Q = 324 R=6 a0


• 324 / 8 → Q = 40 R=4 a1
• 40 / 8 → Q=5 R=0 a2
• 5/8 → Q=0 R=5 a3

Le résultat est donc : 259810 = 50468.

Vous avez un doute sur l’ordre des coefficients dans le résultat final : 50468 ou 64058 ? Une
technique simple consiste à utiliser la méthode pour convertir de la base 10 vers la base
10. On voit alors immédiatement dans quel ordre les chiffres du résultat sont calculés.

Page 3.8 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Le codage des informations

Exemple 2 : convertir le nombre 22110 en binaire (base 2)

La technique reste identique. Elle est toutefois simplifiée dans la mesure où le reste de la division par
2 est 0 ou 1 suivant que le dividende est pair ou impair.

• 221 / 2 → Q = 110 R=1 a0


• 110 / 2 → Q = 55 R=0 a1
• 55 / 2 → Q = 27 R=1 a2
• 27 / 2 → Q = 13 R=1 a3
• 13 / 2 → Q=6 R=1 a4
• 6/2 → Q=3 R=0 a5
• 3/2 → Q=1 R=1 a6
• 1/2 → Q=0 R=1 a7

Le résultat est donc : 22110 = 110111012.

3.2.3 Bases qui sont des puissances de 2


La conversion entre deux bases qui sont des puissances de 2 est très facile. En effet, il suffit de
remarquer que chaque chiffre en base 2n correspondant à un nombre de n chiffres en base 2.

Octal (23) Binaire Hexadécimal (24) Binaire


0 000 0 0000
1 001 1 0001
2 010 2 0010
3 011 3 0011
4 100 4 0100
5 101 5 0101
6 110 6 0110
7 111 7 0111
8 1000
9 1001
A 1010
B 1011
C 1100
D 1101
E 1110
F 1111

Figure 3-7 - Chiffres octal/hexadécimal et nombres binaires

Pour convertir d’une base B = 2n vers le binaire, on transforme chaque chiffre de la base B en sa
représentation en n chiffres binaires ou bits (= binary digits) et on concatène les différents morceaux.

Exemples :

1748 → 001 111 100 → 0011111002


CAFE16 → 1100 1010 1111 1110 → 11001010111111102

© HELMo Campus Guillemins Page 3.9


Le codage des informations Architecture des ordinateurs - Théorie

Pour convertir du binaire vers une base B = 2n, on découpe le nombre binaire en tronçons de n bits
en allant de la droite vers la gauche. Chaque tronçon correspond à un chiffre en base B. Il faut
éventuellement compléter le dernier tronçon de gauche avec des 0.

Exemples :

100101012 → 010 010 101 → 2258


1111000101102 → 1111 0001 0110 → F1616

Pour convertir entre deux bases B et B’ qui sont des puissances de 2, on procède en deux étapes :

1. Conversion de la base B vers le binaire.


2. Conversion du binaire vers la base B’.

Exemple : conversion de l’hexadécimal vers l’octal.

CAFE16 → 1100 1010 1111 1110 → 11001010111111102


→ 001 100 101 011 111 110 → 1453768

3.2.4 Nombres réels : base B vers décimal


Comme pour les nombres entiers, il suffit d’appliquer la formule générale de définition des nombres
et d’additionner les puissances positives et négatives de la base B.

Exemples :
1101,0112 = 1x23 + 1x22 + 0x21 + 1x20 + 0x2-1 + 1x2-2 +1x2-3 = 8+4+1+0,25+0,125 = 13,37510
CAFE,6616 = 12x163 + 10x162 + 15x16 + 14 + 6x16-1 + 6x16-2 = 51.966,398437510

3.2.5 Nombres réels : décimal vers base B


Nous avons vu précédemment comment convertir la partie entière du décimal vers une base B
quelconque (resserrement d’intervalle ou division par la base).

Nous nous intéressons ici à la manière de convertir la partie fractionnaire d’un nombre réel en
utilisant la méthode de multiplication par la base.

Soit N = X,Y un nombre réel. On souhaite convertir la partie fractionnaire Y vers une base B.

La méthode consiste à répéter les opérations suivantes :

• On multiplie Y par la base B.


• On obtient un nombre réel N’ = B x Y = X’,Y’.
• X’ est le premier chiffre de la partie fractionnaire en base B.
• On répète le processus en utilisant Y’, jusqu’à obtenir Y’=0 ou avoir atteint la précision
maximale disponible.

Attention, une partie fractionnaire finie dans une base donnée peut conduire à une
partie fractionnaire qui est illimitée dans une autre base !

Page 3.10 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Le codage des informations

Exemple 1 - Convertir 46,6875 en binaire

Partie entière → 4610 = 1011102

Partie fractionnaire → 0,687510 = 0,10112

• 0,6875 x 2 = 1,375 → 1 + 0,375


• 0,375 x 2 = 0,75 → 0 + 0,75
• 0,75 x 2 = 1,5 → 1 + 0,5
• 0,5 x 2 = 1,0 →1+0

Réponse : 46,687510 = 101110,10112

Exemple 2 - Convertir 0,73 en hexadécimal

• 0,73 x 16 = 11,68 → B + 0,68


• 0,68 x 16 = 10,88 → A + 0,88
• 0,88 x 16 = 14,08 → E + 0,08
• 0,08 x 16 = 1,28 → 1 + 0,28
• 0,28 x 16 = 4,48 → 4 + 0,48
• 0,48 x 16 = 7,68 → 7 + 0,68 (déjà obtenu précédemment)

La séquence AE147 se répète à l’infini. La partie fractionnaire en hexadécimal est donc


illimitée !

Réponse : 0,7310 = 0,BAE147AE147AE147…16

© HELMo Campus Guillemins Page 3.11


Le codage des informations Architecture des ordinateurs - Théorie

3.3 Représentation interne des informations


3.3.1 Des bits, des octets et des mots
Dans les sections précédentes, nous avons expliqué les caractéristiques mathématiques des systèmes
de numération positionnelle et exploré diverses méthodes qui permettent de représenter un nombre
dans n’importe quelle base de numération. Dans les sections qui suivent, nous allons nous intéresser
à la manière de stocker des nombres ainsi que d’autres types de données dans la mémoire d’un
ordinateur.

Un ordinateur stocke les informations en mémoire sous une forme binaire. Ainsi, la plus petite
quantité d’information représentable par un ordinateur est le bit (contraction de « binary digit ») qui
possède deux valeurs distinctes, généralement représentées par 0 et 1. Les bits sont regroupés en
séquences, dont la longueur correspond la plupart du temps à une puissance de 2 : 1, 2, 4, 8, 16, …

La quasi-totalité des puces de mémoire actuelles sont organisées sur la base d’une unité élémentaire
de stockage (cellule mémoire) dont la taille est de 8 bits. Cette quantité de mémoire porte le nom
d’octet (byte). C’est la plus petite quantité d’information accessible de manière individuelle en
mémoire. On rencontre parfois l’appellation anglaise « nibble » pour désigner un demi-octet (4 bits).

Les cellules mémoires sont à leur tour organisées en blocs d’une taille plus importante appelés mots
mémoires. La taille d’un mot mémoire n’est pas standardisée, elle peut être de 16, 32 ou 64 bits
suivant les caractéristiques du processeur utilisé.

3.3.2 Signification d’une séquence de bits


Imaginons que nous puissions observer le contenu de la mémoire avec une loupe. La difficulté
majeure à laquelle nous nous heurtons est que toute information stockée en mémoire est stockée
sous forme binaire. Qu’il s’agisse d’un nombre, d’un texte, d’un son, d’une image, d’une vidéo… tout
n’est en définitive qu’une succession de 0 et de 1 dans la mémoire de l’ordinateur !
Rien ne nous permet de distinguer une séquence binaire qui représente un nombre d’une séquence
binaire qui représente un texte.

Pour illustrer cette situation, considérons le cas d’un bit isolé. Notre seule certitude est que ce bit
peut être dans 2 états distincts et mutuellement exclusifs. Appelons ces deux états : 0 et 1. Que
signifient ces deux états ? Il est impossible de répondre à cette question sans connaître la nature de
l’information qui est représentée par ce bit. La signification de notre bit pourrait être :

• la valeur numérique 0 ou 1 ;
• la réponse oui/non à une question ;
• la valeur vrai/faux d’une condition logique ;
• l’état allumé/éteint d’une lampe ;
• le statut ouvert/fermé d’un magasin ;
• etc.

Page 3.12 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Le codage des informations

En définitive, un bit permet de représenter deux situations possibles dont l’interprétation nécessite
de connaître le contexte dans lequel l’information est utilisée. Si nous disposons de 2 bits, ceux-ci
peuvent prendre 4 configurations distinctes (00, 01, 10, 11) et représenter 4 informations
différentes. Avec 3 bits, nous avons 8 possibilités, avec 4 bits 16 possibilités, etc. Chaque bit
supplémentaire double le nombre de configurations possibles.

En toute généralité, une séquence de 𝑛 bits nous permet de représenter 2𝑛 configurations distinctes.
Inversement, pour représenter 𝑁 informations distinctes par une séquence binaire, nous avons
besoin au minimum de 𝑙𝑜𝑔2 (𝑁) bits. L’interprétation d’une séquence binaire particulière ne peut se
faire qu’en connaissant le contexte d’utilisation de cette séquence.

Par conséquent, lorsque nous nous intéressons à la représentation interne d’un type particulier
d’informations dans un ordinateur, nous devons :

• déterminer le nombre de bits nécessaires pour représenter tous les cas distincts possibles ;
• fixer les règles à utiliser pour définir quelle séquence binaire représente quelle information.

Exemple

Si nous voulons représenter les 26 lettres majuscules (A, B, C, …, Z) par un code binaire, il
nous faut au minimum 𝑙𝑜𝑔2 (26) = 4,7 → 5 bits. Avec 5 bits, nous disposons de 32
possibilités (25 ) représentées par les 32 codes binaires de 00000 à 11111.

Nous pouvons alors décider de la convention suivante : A=0, B=1, C=2, …, Z=25. Ou encore, en
binaire : A=00000, B=00001, C=00010, …, Z=11001. Les 6 combinaisons binaires de 11010
(2610) à 11111 (3110) ne sont pas utilisées.

La relation entre un code binaire et sa signification dépend du contexte et


de la convention de représentation utilisée. Si nous ne connaissons pas ces informations,
il est impossible de déterminer la signification d’un code binaire.

Dans les langages de programmation, ce sont typiquement les instructions de déclaration de données
qui établissent le lien entre une zone mémoire et la signification de son contenu.

Exemples

1. L’instruction Java « int x = -10; » déclare une zone mémoire de 32 bits qui
contiendra la représentation binaire du nombre entier signé -10 suivant la convention de
représentation en complément à 2 (voir section 3.4.3.3).
2. L’instruction C « unsigned short x = 42; » déclare une zone mémoire de 16 bits qui
contiendra la représentation binaire du nombre naturel1 42 (voir section 3.4.1).

1
Rappel : un nombre naturel est un nombre entier positif ou nul.

© HELMo Campus Guillemins Page 3.13


Le codage des informations Architecture des ordinateurs - Théorie

3.4 Représentation des nombres entiers


3.4.1 Décimal codé binaire
3.4.1.1 Le code BCD (Binary Coded Decimal)
Initialement, les ordinateurs ont été inventés pour traiter des données numériques décimales. On a
donc imaginé des codes permettant de représenter les nombres décimaux sans devoir les convertir
au préalable en binaire.

Il existe différents systèmes de représentation décimale des nombres : BCD (Binary Coded Decimal –
Décimal Codé Binaire), code excédent -3, code 2 dans 5, biquinaire, etc. Nous illustrons uniquement
le plus répandu de ces codes, à savoir le code BCD.

Le code BCD est très simple. Il consiste à coder chaque chiffre du nombre décimal en son équivalent
binaire sur 4 bits. Le tableau suivant illustre le code résultant.

Décimal Code BCD


0 0000
1 0001
2 0010
3 0011
4 0100
5 0101
6 0110
7 0111
8 1000
9 1001
Figure 3-8 - Code BCD

Exemple de code BCD : 48256310 → 0100 1000 0010 0101 0110 0011, c’est-à-dire aussi 48256316 !

Remarquons au passage qu’un code sur 4 bits permet de représenter 16 valeurs (cf. hexadécimal).
Or, le code BCD ne doit représenter que les 10 chiffres (0 à 9) : il y a donc 6 codes invalides qui
correspondent aux valeurs 10 à 15.

3.4.1.2 L’addition en BCD


Le code BCD présente l’avantage de simplifier grandement l’encodage et le décodage des nombres
par un opérateur humain. En revanche, il ne facilite pas les opérations de calcul. Regardons à titre
d’exemple comment s’effectue une addition en code BCD.

Exemple 1 : additionner les chiffres 8 et 6.

8 1 0 0 0
+ 6 0 1 1 0
14 1 1 1 0 ← code invalide !!!
0 1 1 0 Si on ajoute 6 au résultat invalide,
0 0 0 1 0 1 0 0 on obtient le code BCD correct !
1 4

Page 3.14 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Le codage des informations

Le résultat de l’addition binaire aboutit à la valeur 14 qui est un code BCD invalide puisque le chiffre
14 n’existe pas dans le code BCD. On souhaiterait obtenir à la place un résultat composé de 2
chiffres : 1 et 4. Pour y arriver, il faut ajouter 6 au résultat (6 correspond au nombre de codes
inutilisés).

Exemple 2 : additionner les nombres 583 et 297.

1 1
5 8 3 0 1 0 1 1 0 0 0 0 0 1 1
+ 2 9 7 0 0 1 0 1 0 0 1 0 1 1 1
8 8 0 1 0 0 0 0 0 1 0 1 0 1 0 ← code invalide !!!
8 0 1 1 0 +6 0 1 1 0 +6
1 0 0 0 0 0 0 0
8 0

L’addition en BCD est semblable à une addition décimale manuelle.


• On additionne les chiffres correspondants de la droite vers la gauche.
• Si le total est supérieur à 9 (dépassement de capacité du point de vue décimal) :
o On reporte 1 dans la colonne suivante.
o On ajoute 6 dans la colonne courante.

Le dépassement de capacité (total des deux chiffres > 9) est détecté de deux manières :

• Le code BCD obtenu est invalide → total entre 10 et 15.


• Un report binaire est généré → total entre 16 et 18.

3.4.2 Les nombres naturels


Oublions le BCD et intéressons-nous à la représentation des nombres en base 2. L’espace mémoire
occupé par la représentation binaire d’un nombre est toujours un nombre entier d’octets. La taille de
cet espace mémoire détermine la valeur maximale qui peut être représentée :

• 8 bits : de 0 à 255 (28-1) octet byte


• 16 bits : de 0 à 65.535 (216-1) entier court short integer
• 32 bits : de 0 à 4.294.967.295 (232-1) entier integer
• 64 bits : de 0 à 18.446.744.073.709.551.615 (264-1) entier long long integer
• k bits : de 0 à (2k-1)

Exemples de représentation en mémoire d’un entier court sur 16 bits

5196610 = 11001010111111102 = CAFE16

bit 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
valeur 1 1 0 0 1 0 1 0 1 1 1 1 1 1 1 0
hexa C A F E

© HELMo Campus Guillemins Page 3.15


Le codage des informations Architecture des ordinateurs - Théorie

253310 = 1001111001012 = 9E516

bit 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
valeur 0 0 0 0 1 0 0 1 1 1 1 0 0 1 0 1
hexa 0 9 E 5

Dans le deuxième exemple, la représentation binaire du nombre 2533 ne nécessite que 12 bits. Les 4
bits inutilisés du mot mémoire ont pour valeur 0.

Au sein d’un mot mémoire, les bits sont conventionnellement numérotés de droite à gauche en
commençant à zéro.

Le bit 0, c’est-à-dire le bit plus à droite, est appelé bit le moins significatif (LSB – Least Significant Bit).
C’est en effet le bit qui contribue le moins à la valeur finale du nombre puisqu’il correspond au
coefficient du terme 20.

Le bit 15 (dans le cas d’un mot de 16 bits), c’est-à-dire le bit plus à gauche, est appelé bit le plus
significatif (MSB – Most Significant Bit). C’est en effet le bit qui contribue le plus à la valeur finale du
nombre puisqu’il correspond au coefficient du terme 215.

Il est possible qu’une opération arithmétique aboutisse à un résultat dont la valeur est supérieure à
la plus grande valeur représentable. On parle dans ce cas d’un dépassement de capacité (overflow).

Exemple :

4523610 + 3272810 = 7796410 c’est-à-dire 1 0011 0000 1000 11002

Les 2 opérandes sont des entiers courts représentables sur 16 bits.


Le résultat nécessite quant à lui 17 bits pour être représenté : il y a un dépassement de capacité !

3.4.3 Les nombres entiers relatifs2


3.4.3.1 Signe et valeur absolue
En mémoire, tout n’est que 0 et 1. Il n’est pas possible d’utiliser une troisième valeur, différente de 0
et de 1, pour indiquer le signe positif ou négatif d’un nombre. Dès lors, une idée très simple pour
représenter un nombre entier relatif (ou signé) est la suivante :

• on utilise par convention le bit situé le plus à gauche dans le mot mémoire (= bit le plus
significatif) pour indiquer le signe (S) affecté à ce nombre ;
• les autres bits du mot mémoire sont utilisés pour représenter la valeur absolue du nombre.

Par convention, le signe + est représenté par le bit S à 0 et le signe - par le bit S à 1.

2
Rappel : un nombre entier relatif est un nombre entier muni d’un signe, il peut donc être positif ou négatif.

Page 3.16 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Le codage des informations

Exemple de représentation en signe et valeur absolue sur 8 bits

Nombre S 6 5 4 3 2 1 0
7410 0 1 0 0 1 0 1 0
-7410 1 1 0 0 1 0 1 0

Suivant la taille de la zone mémoire, l’intervalle des nombres représentables est donc :

• 8 bits : de -127 à +127 octet


• 16 bits : de -32.767 à +32.767 entier court
• 32 bits : de -2.147.483.647 à +2.147.483.647 entier
• 64 bits : de -(263-1) à +(263-1) entier long
• k bits : de -(2k-1-1) à +(2k-1-1)

Cet intervalle est symétrique : il y a autant de nombres positifs que de nombres négatifs.

Inconvénients

• Il existe deux représentations distinctes du zéro : +0 [00000000] et -0 [10000000].


• Les opérations arithmétiques ne sont pas aisées à réaliser, car la gestion du signe est
compliquée.

3.4.3.2 Complément à 1
Dans la représentation en complément à 1, ou complément logique, on utilise également le bit le plus
significatif comme bit de signe. La différence réside dans le fait que pour passer d’un nombre positif
à un nombre négatif, on inverse également tous les bits représentant la valeur absolue du nombre.
Cette représentation facilite grandement la réalisation des opérations arithmétiques. Nous verrons
pourquoi dans la section suivante.

Exemple de représentation en complément à 1 sur 8 bits

Nombre S 6 5 4 3 2 1 0
7410 0 1 0 0 1 0 1 0
Complément à 1 -7410 1 0 1 1 0 1 0 1

L’intervalle des nombres représentables avec k bits est le même que précédemment et il existe
toujours 2 zéros distincts : +0 [00000000] et -0 [11111111].

3.4.3.3 Complément à 2
Le complément à 2, ou complément arithmétique, s’obtient en ajoutant +1 à la valeur du
complément à 1.

Exemple de représentation en complément à 2 sur 8 bits

Nombre S 6 5 4 3 2 1 0
7410 0 1 0 0 1 0 1 0
Complément à 1 -7410 1 0 1 1 0 1 0 1
+1
Complément à 2 -7410 1 0 1 1 0 1 1 0

© HELMo Campus Guillemins Page 3.17


Le codage des informations Architecture des ordinateurs - Théorie

Méthode rapide : on recopie tous les bits du nombre positif en commençant par la droite jusqu’au
premier 1 inclus, après quoi on inverse tous les bits qui suivent.

2375610 = 01011100110011002 → -2375610 = 10100011001101002

La représentation en complément à 2 permet de représenter un nombre négatif de plus. Elle ne


possède plus qu’un seul zéro. Ainsi, avec 8 bits, on va de -128 à +127.

• 0 1111111 = +127
• 0 0000000 = 0
• 1 1111111 = -1
• 1 0000001 = -127
• 1 0000000 = -128 (par convention)

L’intervalle des nombres représentables avec k bits va à présent de -2k-1 à +(2k-1-1). Il est asymétrique.

L’intérêt de la représentation en complément à 2 est de faciliter grandement les opérations


arithmétiques : pour soustraire un nombre, il suffit d’ajouter son complément à 2. En pratique, on
additionne tous les chiffres et on laisse tomber la retenue finale éventuelle. Cette technique de
soustraction est très facile à mettre en œuvre dans un ordinateur.

Exemples :

1510 = 000011112 → -1510 = 11110001cpl2


4510 = 001011012 → -4510 = 11010011cpl2

74 01001010 23 00010111
-15 +11110001 -45 +11010011
59 100111011 -22 11101010

Un dépassement de capacité est détecté par l’une ou l’autre des conditions suivantes :

• la retenue générée sur le bit de signe est différente de celle générée sur le bit juste avant ;
• les deux opérandes sont de même signe, lequel est différent de celui du résultat.

Exemples :

7410 = 010010102 → -7410 = 10110110cpl2

01001010 10110110 ← reports


74 01001010 -74 10110110
+74 +01001010 -74 +10110110
148 10010100 -148 01101100
(= -108) (= 108)

Page 3.18 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Le codage des informations

3.4.3.4 Extension de signe


Si nous estimons que la quantité de mémoire allouée à la représentation d’un nombre est
insuffisante pour permettre la réalisation d’une opération arithmétique sans provoquer de
dépassement de capacité, nous pouvons décider d’augmenter la quantité de mémoire allouée à ce
nombre et passer par exemple de 8 bits à 16, 32 ou 64 bits.

Pour réaliser cette opération, nous devons cependant tenir compte de la représentation utilisée :

• s’il s’agit d’un nombre naturel (non signé), il suffit d’ajouter des bits à 0 à gauche ;
• dans le cas d’un nombre entier signé représenté en signe et valeur absolue, il faut déplacer le
bit de signe dans la nouvelle position la plus à gauche (bit le plus significatif) et compléter la
valeur absolue en lui ajoutant des bits à 0 à gauche ;
• enfin, pour « agrandir » un nombre entier signé codé en complément à 2 (ou à 1), il convient
de recopier le bit de signe dans tous les bits ajoutés à gauche. Cette opération porte le nom
d’extension de signe.

Exemples

Nombre naturel 74 = 01001010 → 0000000001001010

Signe + valeur +74 = 01001010 → 0000000001001010


-74 = 11001010 → 1000000001001010

Complément +74 = 01001010 → 0000000001001010


-74 = 10110110 → 1111111110110110

3.4.3.5 Représentation biaisée


Nous terminons cette partie consacrée à la représentation des nombres entiers relatifs par une
technique un peu particulière, appelée représentation biaisée (ou décalée). Cette technique sera
notamment utilisée pour représenter l’exposant des nombres exprimés en virgule flottante (voir
section 3.5.2).

Considérons un code binaire sur 8 bits. Il permet de représenter 256 (=28 ) valeurs distinctes. Une
interprétation possible de ces 256 codes binaires est qu’ils représentent les nombres naturels de 0 à
255. Cette interprétation n’est pas obligatoire : c’est juste une possibilité parmi d’autres.

Supposons à présent que nous devions représenter des valeurs entières de températures comprises
entre -50°C et +205°C. Nous pouvons bien sûr décider d’utiliser une représentation signée en
complément à deux. Cependant, pour couvrir cette plage de valeurs, nous devons au minimum
utiliser un nombre signé sur 16 bits, ce qui représente un gaspillage de place considérable.

Une autre possibilité est de constater que notre intervalle de températures n’est rien d’autre qu’un
intervalle de 256 nombres entiers consécutifs et d’utiliser une convention appelée notation biaisée
pour les représenter en mémoire. Cette technique consiste à ajouter une quantité donnée, appelée
biais, aux nombres entiers que l’on souhaite représenter, afin de mettre l’intervalle souhaité en
correspondance avec celui des nombres naturels de 0 à 255.

© HELMo Campus Guillemins Page 3.19


Le codage des informations Architecture des ordinateurs - Théorie

Remarque : en fonction de la plage de valeurs à représenter, le biais peut être une quantité positive
ou négative. Ainsi, pour représenter l’intervalle [+723,+978], le biais à utiliser serait de -723.

Pour notre exemple des températures, nous devons utiliser un biais de +50 :
• le nombre effectif -50 est représenté par la valeur biaisée 0,
• le nombre effectif 0 est représenté par la valeur biaisée 50,
• le nombre effectif +205 est représenté par la valeur biaisée 255.

En partant du nombre effectif, il faut donc ajouter le biais pour obtenir la valeur biaisée. Celle-ci est
ensuite stockée en mémoire comme un nombre naturel, c’est-à-dire en binaire et sans bit de signe.

Inversement, en partant de la représentation binaire stockée en mémoire, il faut d’abord la convertir


en décimal pour obtenir la valeur biaisée puis soustraire le biais pour retrouver le nombre effectif.

Exemple
T° = -15°C Valeur biaisée = -15 + 50 = 35 En mémoire : 00100011
En mémoire = 01011100 Valeur biaisée = 92 T° = 92 – 50 = 42°C
Les T° inférieures à -50°C et supérieures à +205°C ne sont pas représentables sur 8 bits !

3.4.4 Les représentations petit-boutiste et gros-boutiste


Nous venons d’expliquer différentes conventions qui permettent de représenter des nombres entiers
au moyen de séquences binaires de 8, 16, 32 ou 64 bits. Lorsque cette représentation comporte
plusieurs octets (2, 4 ou 8), la question se pose de savoir dans quel ordre ces différents octets seront
placés en mémoire.

Considérons par exemple le nombre entier non signé 271284731610 dont la représentation
hexadécimale est A1B2C3D416. La représentation de ce nombre nécessite 32 bits, c’est-à-dire 4
octets dont les valeurs hexadécimales sont respectivement A1, B2, C3 et D4. Ces 4 octets peuvent
être placés en mémoire de deux manières différentes :

… N N+1 N+2 N+3 … ← Adresse mémoire


… A1 B2 C3 D4 … Représentation gros-boutiste (big-endian)
… D4 C3 B2 A1 … Représentation petit-boutiste (little-endian)
Figure 3-9 - Représentations petit-boutiste et gros-boutiste

La première ligne du tableau montre que les octets du mot de 32 bits sont placés en mémoire en
commençant par l’octet de poids fort « A1 » pour terminer avec l’octet de poids faible « D4 ». Cette
manière de procéder porte le nom de gros-boutiste (big-endian en anglais).

La deuxième ligne du tableau montre que les octets du mot de 32 bits sont placés en mémoire en
commençant par l’octet de poids faible « D4 » pour terminer avec l’octet de poids fort « A1 ». Cette
manière de procéder porte le nom de petit-boutiste (little-endian en anglais).

Le boutisme (endianness en anglais) dépend principalement de l’architecture interne d’un processeur


et de l’organisation de la mémoire qui en découle. Il n’y a pas d’argument technique fondé pour

Page 3.20 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Le codage des informations

justifier la supériorité d’une approche sur l’autre. Certains processeurs, comme le processeur MIPS
dont nous parlerons au Chapitre 5, supportent même les deux modes et peuvent fonctionner dans
l’un ou dans l’autre en fonction d’un choix logiciel ou matériel. On parle alors de bi-boutisme.

Dans de nombreuses situations, le choix de l’une ou l’autre approche n’a aucune incidence sur le
programmeur puisque la représentation des données et leur stockage en mémoire sont pris en
charge de manière transparente par le compilateur et par le processeur.

La situation se complique dans des situations telles que l’échange et le traitement de fichiers de
données ou la transmission d’informations sur un réseau informatique. Une fois que les données
sont « externalisées », c’est-à-dire ne se trouvent plus dans l’environnement fermé d’une
architecture spécifique, il faut se mettre d’accord sur une convention d’ordonnancement des octets,
sous peine d’avoir des surprises.

« On appelle cela le problème NUXI, en effet si on veut envoyer la chaîne « UNIX » en regroupant deux
octets par mot entier de 16 bits sur une machine de convention différente, alors on obtient NUXI. Ce
problème a été découvert en voulant porter une des premières versions d'Unix d'un PDP-11 mi-
boutiste sur une architecture IBM gros-boutiste.

Le protocole IP définit un standard, le network byte order (soit ordre des octets du réseau). Dans ce
protocole, les informations binaires sont en général codées en paquets, et envoyées sur le réseau,
l'octet de poids le plus fort en premier, c'est-à-dire selon le mode gros-boutiste et cela quel que soit le
boutisme naturel du processeur hôte. » [ Source : https://fr.wikipedia.org/wiki/Boutisme ]

Certains algorithmes mathématiques qui traitent des séquences d’octets en les regroupant en mots
de 16, 32 ou 64 bits peuvent également imposer un boutisme particulier. Ainsi, fonction de hachage
cryptographique MD5 qui calcule l’empreinte numérique d’un fichier utilise la convention petit-
boutiste (little-endian), alors que sa remplaçante, la fonction de hachage SHA-256, utilise quant à elle
la convention gros-boutiste (big-endian). Il faut donc rester attentif à cette problématique !

© HELMo Campus Guillemins Page 3.21


Le codage des informations Architecture des ordinateurs - Théorie

3.5 Représentation des nombres réels


3.5.1 Virgule fixe
La notion de virgule n’existe pas plus dans la mémoire d’un ordinateur que celle de signe : tout n’est
qu’une succession de 0 et de 1. C’est le programme qui donne une signification à ces bits.

Comment peut-on dès lors représenter un nombre réel en mémoire ? Nous avons vu précédemment
que 46,687510 = 101110,10112. Il nous faut donc au minimum 6 bits pour représenter la partie
entière et 4 bits pour représenter la partie décimale.

La représentation en virgule fixe consiste à définir de manière fixe le nombre de bits attribués à la
partie entière et à la partie fractionnaire d’un nombre réel. Ainsi, si on représente un nombre réel sur
32 bits, on peut décider que 16 bits sont alloués à la partie entière et 16 bits à la partie fractionnaire.

Cette manière de procéder n’est pas très flexible. Suivant le type de calculs effectués, on peut avoir
besoin d’une partie entière importante (> 16 bits) et se contenter de peu de précision dans la partie
fractionnaire, ou devoir manipuler des valeurs qui ne sont pas très grandes, mais qui demandent au
contraire une grande précision, c’est-à-dire un nombre important de décimales après la virgule.

La représentation en virgule fixe ne permet pas de satisfaire simultanément ces deux objectifs sans
devoir utiliser un espace mémoire qui devient vite déraisonnable. Ainsi, si on voulait utiliser un
format unique en virgule fixe pour représenter des longueurs en mètres aussi diverses que la
distance entre la Terre et le Soleil (±150 millions de km = 1,5 x 1011 m) ou le rayon d’un atome
d’oxygène (60 pm = 6 x 10-11 m), il faudrait utiliser 10 octets (80 bits) !

Pour toutes ces raisons, on a imaginé un système plus flexible : la représentation en virgule flottante.

Notons cependant que la représentation en virgule fixe est toujours utilisée pour certaines
applications scientifiques spécifiques, car dans certains contextes spécifiques elle peut s’avérer
beaucoup plus performante que la représentation en virgule flottante.

3.5.2 Virgule flottante


L’idée à la base de la représentation en virgule flottante est à rapprocher de la notation scientifique,
à savoir que l’on peut représenter un nombre réel sous la forme :

𝑁𝑜𝑚𝑏𝑟𝑒⁡ = ⁡𝑀𝑎𝑛𝑡𝑖𝑠𝑠𝑒⁡𝑥⁡𝐵𝑎𝑠𝑒⁡𝐸𝑥𝑝𝑜𝑠𝑎𝑛𝑡

Ainsi, le nombre réel 1.234,567 peut aussi s’exprimer comme 1,234567 x 103.

On peut considérer que la mantisse (ou significande) donne l’information « utile », la précision, et
que l’exposant donne l’ordre de grandeur du nombre.

Nous savons également que l’espace disponible pour représenter un nombre en mémoire est limité.
On utilisera donc la notation précédente afin de mémoriser un maximum de chiffres significatifs,
c’est-à-dire apportant une information utile.

Page 3.22 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Le codage des informations

Ainsi, si on considère le nombre 0,00012, on peut le réécrire sous la forme 1,2 x 10-4. De même, pour
un grand nombre tel que 25 milliards, plutôt que d’écrire 25.000.000.000, on préférera la forme
25 x 109, ou mieux encore 2,5 x 1010. Cette dernière forme est appelée notation scientifique
normalisée.

La forme normalisée d’un nombre réel décimal s’obtient en ajustant l’exposant de telle sorte que la
partie entière de la mantisse comporte 1 seul chiffre non nul compris entre 1 et 9. En toute rigueur,
le nombre zéro ne peut donc pas être représenté de manière normalisée.

Exemple : la forme normalisée de 12,4 est 1,24 x 101. A contrario, 0,0124 x 103 n’est pas normalisé !

Parlons à présent de la représentation des nombres réels en virgule flottante telle qu’elle est définie
par le standard IEEE 754. Cette représentation consiste à stocker en mémoire la forme normalisée
d’un nombre réel de la manière suivante :

• la mantisse est représentée par son signe et sa valeur absolue ;


• l’exposant utilise la notation biaisée.

Le contenu du mot mémoire ressemble donc à ceci :

SM EXPOSANT MANTISSE

où SM est le signe de la mantisse. Par convention, 0 signifie + (positif) et 1 signifie – (négatif).

La forme normalisée d’un nombre réel binaire définie par le standard IEEE 754 correspond à celle de
la notation scientifique. Elle s’obtient en ajustant l’exposant de telle sorte que la partie entière de la
mantisse soit égale à 1, qui est la seule valeur non nulle possible en binaire. La seule exception est le
nombre 0 qui est représenté par un mot mémoire dont tous les bits sont à 0.

Exemple : 11,2510 = 1011,012 → 1,01101 x 23

Le standard IEEE 754 définit le nombre de bits alloués à l’exposant et à la mantisse en fonction de la
précision choisie, ainsi que le biais appliqué à l’exposant.

Précision SM EXPOSANT / BIAIS MANTISSE


Simple (32 bits) 1 bit 8 bits / +127 23 bits
Double (64 bits) 1 bit 11 bits / +1023 52 bits

En ce qui concerne l’exposant, on constate que les valeurs représentables vont de -127 (0-127) à
+128 (255-127) en simple précision et de -1023 (0-1023) à +1024 (2047-1023) en double précision.

Par ailleurs, comme le premier bit de la mantisse normalisée vaut toujours 1, il n’est pas nécessaire
de le stocker. On stocke uniquement la partie fractionnaire de la mantisse, ce qui permet de gagner
un peu de précision supplémentaire. Le traitement est en revanche plus compliqué.

© HELMo Campus Guillemins Page 3.23


Le codage des informations Architecture des ordinateurs - Théorie

3.5.3 Conversion vers le format IEEE 754


La méthode de conversion vers la représentation en virgule flottante IEEE 754 est très systématique.
Elle fait appel aux différentes techniques de conversion vues dans les sections précédentes.

Nous pouvons résumer le processus de conversion comme suit :

1. Identifier le signe du nombre à convertir.


2. Convertir la partie entière du nombre réel décimal vers son équivalent binaire.
3. Convertir la partie fractionnaire du nombre réel décimal vers son équivalent binaire.
4. Normaliser le nombre réel binaire obtenu aux étapes 2 et 3, ce qui nous donne la valeur de la
mantisse à stocker et la valeur de l’exposant.
5. Calculer la valeur décimale biaisée de l’exposant en lui ajoutant 127 (simple précision).
6. Convertir la valeur décimale biaisée de l’exposant vers son équivalent binaire sur 8 bits
(simple précision).
7. Assembler les différents morceaux pour obtenir la représentation finale en virgule flottante.

Pour rappel, on ne stocke pas le bit qui correspond à la partie entière de la mantisse. Si la partie
fractionnaire de la mantisse comporte moins de 23 bits (simple précision), on complète à droite avec
des zéros. Si elle comporte plus de 23 bits, on laisse tomber les bits excédentaires, ce qui entraîne
une inévitable perte de précision.

Exemple 1 : convertir 11,2510 vers sa représentation en virgule flottante simple précision IEEE 754.

1. Signe positif → 0
2. Conversion de la partie entière : 1110 = 10112
3. Conversion de la partie fractionnaire : 0,2510 = 0,012
→ Nombre binaire = 1011,012
4. Nombre binaire normalisé : 1,01101 x 23
→ Mantisse à stocker = 01101 (on laisse tomber le 1 de la partie entière)
→ Exposant = 3
5. Exposant biaisé : 3 + 127 = 13010
6. Conversion de l’exposant biaisé : 13010 = 100000102
7. Résultat final :

S EXPOSANT MANTISSE
0 1 0 0 0 0 0 1 0 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

Exemple 2 : -0,414062510= - 0,01101012 → - 1,10101 x 2-2

Signe négatif → 1
Mantisse à stocker : 10101 (on laisse tomber le 1 de la partie entière)
Exposant biaisé : -2 + 127 = 12510 = 11111012

S EXPOSANT MANTISSE
1 0 1 1 1 1 1 0 1 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

Page 3.24 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Le codage des informations

3.5.4 Conversion depuis le format IEEE 754


Pour obtenir la valeur décimale d’un nombre en virgule flottante représenté en suivant la standard
IEEE 754, il suffit de réaliser les opérations décrites à la section précédente en ordre inverse.

1. Isoler les différentes portions du code binaire : S, E, M.


2. Le bit de signe S donne le signe du nombre réel (0=positif, 1=négatif).
3. Convertir la portion « E » du code binaire vers le décimal et soustraire le biais (127 ou 1023)
pour obtenir l’exposant du nombre réel normalisé.
4. Exprimer le nombre réel sous sa forme binaire normalisée : 1,<M> x 2<exposant>
5. Dénormaliser le nombre, c’est-à-dire ajuster la position de la virgule pour annuler l’exposant.
Exemples : 1,110110 x 24 = 11101,10 1,011011 x 2-3 = 0,001011011
6. Convertir le nombre binaire dénormalisé vers le décimal et l’affecter du signe correct.

Exemple

S EXPOSANT MANTISSE
1 1 0 0 0 0 1 0 1 1 0 1 1 0 1 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0
Signe : 1 → nombre négatif

Exposant biaisé : 100001012 = 13310


Exposant effectif : 133 - 127 = 6

Nombre binaire normalisé : 1,10110101101 x 26


Nombre binaire dénormalisé : 1101101,01101

Nombre réel : 11011012 = 10910 / 0,011012 = 0,4062510


Réponse finale : -109,40625

3.5.5 Différences entre nombres réels et nombres en virgule


flottante
Les nombres réels et les nombres en virgule flottante sont des notions très différentes. Ainsi, les
nombres réels constituent un continuum qui va de −∞ à +∞. Les nombres en virgule flottante
utilisent quant à eux une représentation binaire basée sur deux valeurs discrètes (0 et 1) et limitée
par un espace mémoire fini. La conséquence directe de cette situation est que les nombres en virgule
flottante ne permettent pas de représenter tous les nombres réels.

• Il existe une infinité de nombres réels, alors que la quantité de nombres en virgule flottante
est limitée par l’espace mémoire alloué à leur représentation : ±232 nombres (ou ±264).
Ainsi, si on essaie de stocker le nombre réel 390411213,16718 en float simple précision, le
nombre effectivement stocké est 390411200,0. On a donc une erreur de 13,16718 !

• Quel que soit le nombre réel choisi, il y en a toujours un qui est plus grand en valeur absolue.
La plus grande valeur absolue représentable sur 32 bits en virgule flottante est :

± 1,11111111111111111111111 x 2127 ≈ ± 3,4 x 1038

© HELMo Campus Guillemins Page 3.25


Le codage des informations Architecture des ordinateurs - Théorie

Si les opérations arithmétiques effectuées aboutissent à une valeur absolue supérieure à ce


maximum, il y a un dépassement de capacité (overflow). L’exposant est trop grand pour être
représenté (supérieur à +127).
Pour indiquer un dépassement de capacité, le standard IEEE 754 réserve une signification
spéciale à la valeur d’exposant +128 : elle sert à indiquer une valeur infinie.

± 1,00000000000000000000000 x 2128 = ± infini

S EXPOSANT MANTISSE
0/1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

Attention : si l’exposant vaut +128, tous les bits de la mantisse doivent être nuls. Sinon, le
nombre n’est pas valide. Il y a une erreur de type NaN ( Not a Number).

• Quel que soit le nombre réel choisi, il y en a toujours un qui est plus petit en valeur absolue.
La plus petite valeur absolue normalisée représentable sur 32 bits en virgule flottante est :

± 1,00000000000000000000000 x 2-126 ≈ ± 1,175 x 10-38 (nombres normalisés)

Pourquoi s’arrêter à 2-126, alors qu’il est possible de représenter un exposant égal à -127 ? Le
standard IEEE permet de gagner encore un peu de précision au moyen de nombres dits non
normalisés. Ceux-ci correspondent aux nombres de la forme ± 0, ... x 2-127. Ils sont appelés
« non normalisés », car la partie entière de la mantisse vaut 0 et pas 1. La plus petite valeur
absolue non normalisée représentable sur 32 bits en virgule flottante est par conséquent :

± 0,00000000000000000000001 x 2-127 ≈ ± 1,4 x 10-45 (nombres non normalisés)

Si les opérations arithmétiques effectuées aboutissent à une valeur absolue inférieure à ce


minimum, il y a un sous-passement de capacité (underflow). L’exposant est trop petit pour
être représenté (inférieur à -127).

Pour indiquer un sous-passement de capacité, le standard IEEE 754 utilise la valeur zéro.

• Quels que soient les deux nombres réels choisis, il existe toujours un nombre réel situé entre
eux. En d’autres termes, l’écart entre deux nombres réels peut se réduire indéfiniment, ce
qui se traduit par un nombre potentiellement infini de chiffres dans la partie fractionnaire.
En virgule flottante, le nombre de chiffres significatifs est limité par l’espace mémoire alloué
à la mantisse. L’écart minimum entre deux nombres consécutifs est donc fonction de la taille
de la mantisse, mais aussi de l’exposant :

± 0,00000000000000000000001 x 2k

Toutes ces différences expliquent que le calcul numérique en virgule flottante n’est pas équivalent au
calcul sur des nombres réels. Il peut conduire à des erreurs catastrophiques si on n’y prête pas
attention. L’analyse numérique est une discipline qui s’intéresse à cette problématique et qui vise à
concevoir des algorithmes capables de résoudre numériquement des problèmes de mathématiques
continues avec une précision satisfaisante.

Page 3.26 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Le codage des informations

3.6 Données non numériques


3.6.1 Introduction
Nous avons vu à la section 3.4.1 que le code BCD permet de représenter facilement les chiffres
décimaux, car il y a une correspondance directe entre un chiffre et la valeur binaire du code BCD qui
le représente : 510 → 01102 → 0110BCD.

Très vite, il a été nécessaire de représenter d’autres informations que des nombres. On a donc
inventé des codes alphanumériques qui permettent de représenter des chiffres, des lettres, des
signes de ponctuation, des opérateurs arithmétiques, etc.

Dans un code alphanumérique, la correspondance entre un caractère et son code est donnée par une
table de codage qui est propre au code considéré.

Nous présentons brièvement ci-après trois codes alphanumériques représentatifs de l’évolution des
techniques de codage : EBCDIC, ASCII et Unicode.

3.6.2 EBCDIC (Extended Binary Coded Decimal Interchange Code)


Comme son nom l’indique, le code EBCDIC est une version étendue du code BCD. Chaque caractère
est codé sur 8 bits, ce qui autorise 256 caractères différents. Une particularité de l’EBCDIC est
d’utiliser 4 bits de zone et 4 bits numériques. Le tableau suivant présente une partie de la table de
codage EBCDIC.
Caractère Bits de zone Bits numériques Valeur hexa.
0 1111 0000 F0
1 1111 0001 F1
2 1111 0010 F2
3 1111 0011 F3
4 1111 0100 F4
5 1111 0101 F5
6 1111 0110 F6
7 1111 0111 F7
8 1111 1000 F8
9 1111 1001 F9
A 1100 0001 C1
B 1100 0010 C2
C 1100 0011 C3
D 1100 0100 C4
E 1100 0101 C5
F 1100 0110 C6
G 1100 0111 C7
H 1100 1000 C8
I 1100 1001 C9
J 1101 0001 D1
K 1101 0010 D2
L 1101 0011 D3
M 1101 0100 D4
N 1101 0101 D5
O 1101 0110 D6
P 1101 0111 D7
Q 1101 1000 D8
R 1101 1001 D9

Figure 3-10 - Le code EBCDIC (extrait)

© HELMo Campus Guillemins Page 3.27


Le codage des informations Architecture des ordinateurs - Théorie

3.6.3 ASCII (American Standard Code for Information Interchange)


Le code ASCII est probablement le code le plus connu et utilisé. Chaque caractère du code ASCII est
codé sur 7 bits, ce qui permet de représenter 128 caractères au total (codes de 0 à 127). En pratique,
un caractère ASCII est stocké dans une cellule mémoire de 8 bits (octet). Les codes 128 à 255 ont été
ajoutés par IBM (bordures, smiley…), mais ils ne sont pas supportés par tous les d’ordinateurs.

Code Nom Code Nom Code Car Code Car Code Car Code Car Code Car Code Car
0 NUL 16 DLE 32 Esp. 48 0 64 @ 80 P 96 ` 112 p
1 SOH 17 DC1 33 ! 49 1 65 A 81 Q 97 a 113 q
2 STX 18 DC2 34 " 50 2 66 B 82 R 98 b 114 r
3 ETX 19 DC3 35 # 51 3 67 C 83 S 99 c 115 s
4 EOT 20 DC4 36 $ 52 4 68 D 84 T 100 d 116 t
5 ENQ 21 NAK 37 % 53 5 69 E 85 U 101 e 117 u
6 ACK 22 SYN 38 & 54 6 70 F 86 V 102 f 118 v
7 BEL 23 ETB 39 ' 55 7 71 G 87 W 103 g 119 w
8 BS 24 CAN 40 ( 56 8 72 H 88 X 104 h 120 x
9 HT 25 EM 41 ) 57 9 73 I 89 Y 105 i 121 y
10 LF 26 SUB 42 * 58 : 74 J 90 Z 106 j 122 z
11 VT 27 ESC 43 + 59 ; 75 K 91 [ 107 k 123 {
12 FF 28 FS 44 , 60 < 76 L 92 \ 108 l 124 |
13 CR 29 GS 45 - 61 = 77 M 93 ] 109 m 125 }
14 SO 30 RS 46 . 62 > 78 N 94 ^ 110 n 126 ~
15 SI 31 US 47 / 63 ? 79 O 95 _ 111 o 127 DEL

Figure 3-11 - Le code ASCII

Les codes 0 à 31 correspondent à des caractères de contrôle qui sont utilisés pour effectuer la
signalisation lors de la transmission de données ou pour contrôler l’affichage sur un terminal
(tabulation, retour à la ligne, …).

3.6.4 Unicode et représentation UTF-8


Comme son nom l’indique, le code ASCII est d’origine américaine. Dès lors, il n’a pas été conçu pour
supporter les caractères accentués !

D’autre part, les caractères accentués ne sont pas identiques en français (é, è, à, …), en allemand (ü,
ä, …) ou en espagnol (ñ, …). Les langues scandinaves utilisent des caractères additionnels tels que le
ø. Certains pays utilisent un alphabet totalement différent du nôtre : cyrillique, arabe, japonais, etc.
Enfin, des usages particuliers nécessitent des alphabets ou des caractères spécifiques : smileys,
alphabet morse, notes de musique, alphabet braille…

Pour toutes ces raisons, l’organisation internationale de normalisation (ISO) d’une part et un
groupement d’entreprises du secteur informatique d’autre part, ont décidé de définir un jeu de
caractères universel et extensible : le standard UNICODE.

L’idée initiale d’Unicode était d’assigner à chaque caractère un code unique (point de code - code
point) sur 16 bits. Chaque caractère possède un code de taille fixe, ce qui facilite l’écriture des
logiciels. Les codes 0 à 255 correspondent aux caractères du code ASCII, ce qui permet une transition
aisée vers Unicode.

Malheureusement, en se limitant à 16 bits, on ne peut représenter que 65.536 caractères différents.


Or, les langues asiatiques telles que le chinois, le coréen ou le japonais contiennent énormément de

Page 3.28 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Le codage des informations

symboles (idéogrammes) différents. L’alphabet japonais kanji complet contient à lui seul plus de
50.000 idéogrammes !!!

Il a donc fallu étendre l’espace de codage d’Unicode qui contient actuellement 17 plans de 65.536
caractères chacun. Soit un total de 1.114.112 caractères dont environ 138.000 sont déjà alloués dans
la version 13.0 du standard, publiée en mars 2020.

Il existe différentes représentations internes des points de code Unicode. Une des représentations
très répandues, notamment sur Internet, est appelée UTF-8 (UTF = Unicode Transformation Format).
UTF-8 représente un caractère Unicode sur 1 à 4 octets.

Une caractéristique intéressante de la représentation UTF-8 est qu’elle est rétrocompatible avec le
code ASCII. Les caractères ASCII de 0 à 127 (bit de poids fort = 0) sont représentés tels quels, sur 1
octet. Si le bit de poids fort du premier octet est mis à 1, cela signifie que le caractère est stocké sur
plusieurs octets. Pour obtenir plus de détails sur le codage UTF-8, consultez un des nombreux sites
Internet consacrés à ce sujet.

3.6.5 Représentation des données dans les langages de


programmation
Jusqu’à présent, nous avons parlé de la représentation de données élémentaires : nombres et
caractères alphanumériques. Les langages de programmation permettent de manipuler des types de
données additionnels, plus ou moins complexes :

• Valeurs booléennes (vrai/faux)


• Chaînes de caractères
• Tableaux
• Listes chaînées
• Arbres
• Etc.

Chaque langage peut utiliser ses propres conventions pour représenter une donnée en mémoire.
Ainsi, le langage C ne définit pas de type booléen, mais il considère qu’une valeur numérique nulle
signifie faux et qu’une valeur numérique non nulle signifie vrai.

Le langage C stocke une chaîne de caractères en mémoire comme une succession de caractères
terminée par un caractère spécial qui en indique la fin. Le langage Java, quant à lui, n’utilise pas de
délimiteur de fin de chaîne, mais il stocke explicitement la longueur de celle-ci.

Toutes ces spécificités seront abordées dans d’autres cours (Programmation de base, Structures
avancées de données…).

© HELMo Campus Guillemins Page 3.29


Le codage des informations Architecture des ordinateurs - Théorie

3.7 Détection et correction d’erreurs


3.7.1 Introduction
Nous avons vu dans les sections précédentes comment il est possible de représenter des
informations sous une forme binaire. Ces informations sont alors stockées en mémoire ou sur un
support de stockage pour être manipulées par un programme, transmises à un autre ordinateur par
un réseau, etc.

Les puces mémoires ne sont pas infaillibles. Les supports de stockage (disques durs, clés USB) non
plus. Il est donc possible que des erreurs apparaissent dans les données stockées. De même, des
phénomènes parasites peuvent introduire des erreurs (voire des pertes) de données lors d’une
transmission sur un réseau.

Différentes techniques d’encodage permettent d’ajouter des informations supplémentaires aux


données dont on souhaite assurer l’intégrité, afin de détecter et d’éventuellement corriger les
erreurs.

3.7.2 Codes autovérificateurs (bit de parité)


La technique la plus simple pour détecter une erreur est le contrôle de parité. Elle consiste à ajouter
un bit supplémentaire, appelé bit de parité, aux données à protéger.

La valeur du bit de parité est calculée afin que le nombre total de bits à 1 soit pair (parité paire) ou
impair (parité impaire). Supposons par exemple que le texte « HELLO » encodé en ASCII sur 7 bits
doit être transmis entre deux ordinateurs. Voici le code résultant :

Car. ASCII Parité paire Parité impaire


H 1001000 0 1001000 1 1001000
E 1000101 1 1000101 0 1000101
L 1001100 1 1001100 0 1001100
L 1001100 1 1001100 0 1001100
O 1001111 1 1001111 0 1001111

Supposons que l’on utilise un contrôle de parité pair et que le caractère ‘E’ soit modifié durant la
transmission en [11000001]. Le récepteur constatera que le nombre de bits à 1 du deuxième
caractère n’est plus pair. Il en déduit qu’une erreur s’est produite.

Le contrôle de parité (pair ou impair) permet de détecter une erreur lorsqu’un nombre impair de bits
sont en erreur. En revanche, il ne permet ni de détecter un nombre pair de bits en erreur ni de
déterminer où se trouvent les erreurs. Dans le cas d’une transmission de données, il faudra envoyer à
nouveau les données erronées.

Le contrôle au moyen d’un bit de parité convient uniquement dans des circonstances où le taux
d’erreur et la probabilité d’erreurs multiples sont très faibles.

Page 3.30 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Le codage des informations

3.7.3 Codes autocorrecteurs


Si on veut non seulement détecter, mais aussi corriger une erreur, on doit recourir à des méthodes
plus sophistiquées.

3.7.3.1 Double parité


En plus du contrôle de parité sur chaque caractère (contrôle « horizontal »), on groupe les caractères
à transmettre par bloc et on effectue également un contrôle de parité « vertical » bit par bit pour
l’ensemble des caractères du bloc.

Dans l’exemple ci-dessous, le contrôle horizontal utilise un bit de parité pair (PP), le contrôle vertical
utilise un bit de parité impair (PI). Le bit 2 du caractère ‘E’ est en erreur, comme précédemment.

Car. b6 b5 b4 b3 b2 b1 b0 PP
H 1 0 0 1 0 0 0 0
E 1 0 0 0 0 0 1 1
L 1 0 0 1 1 0 0 1
L 1 0 0 1 1 0 0 1
O 1 0 0 1 1 1 1 1
PI 0 1 1 1 1 0 1

Le contrôle des parités indique une erreur dans le deuxième caractère et dans la colonne ‘b2’. C’est
donc le bit 2 du caractère ‘E’ qui est en erreur et nous pouvons le corriger.

Le système de la double parité permet de détecter un nombre impair d’erreurs dans une ligne ou
dans une colonne. Il permettra également de corriger un nombre impair d’erreurs, si elles
surviennent toutes dans la même ligne ou dans la même colonne.

3.7.3.2 Code de Hamming


Le code de Hamming est une version plus élaborée du test de parité présenté à la section 3.7.2. Nous
présentons dans cette section un code de Hamming qui permet de corriger 1 bit en erreur.

Il existe de nombreuses variantes plus complexes du code de Hamming. Elles sortent du cadre de ce
cours.

Imaginons que nous souhaitions transmettre une donnée de d bits. Nous allons lui ajouter une
information de contrôle de k bits qui nous permettra de détecter et de corriger 1 bit en erreur.

La longueur totale m du message transmis est donc : m = d + k bits.

L’information de contrôle doit nous permettre d’identifier l’absence d’erreur ou celui des m bits du
message qui est erroné, ce qui nous donne m+1 possibilités : pas d’erreur, bit 1, bit 2, … bit m. Le
nombre de bits de contrôle k doit donc être tel que 2k ≥ m+1. Idéalement, afin d’éviter le gaspillage,
on s’arrangera pour que la taille du message soit égale à m = 2k-1, c’est-à-dire d = 2k-1-k ce qui
correspond au maximum de bits de données utiles pour une valeur de k donnée.

© HELMo Campus Guillemins Page 3.31


Le codage des informations Architecture des ordinateurs - Théorie

Exemples :

• Pour k = 3 bits, mmax = 23-1 = 7 bits → d = 7-3 = 4 bits de données.


Un code de Hamming de 7 bits permet de protéger au maximum 4 bits de données au moyen
de 3 bits de contrôle.
• Pour k = 4 bits, mmax = 24-1 = 15 bits → d = 15-4 = 11 bits de données.
Un code de Hamming de 15 bits permet de protéger un maximum de 11 bits de données au
moyen de 4 bits de contrôle.

Si on numérote les bits du code de Hamming de droite à gauche en commençant par 1, les bits de
contrôle sont ceux dont le numéro correspond à une puissance de 2, à savoir : 1, 2, 4, 8, 16, … Les
autres positions sont occupées par les bits de données.

7 6 5 4 3 2 1
d4 d3 d2 k3 d1 k2 k1

Chaque bit de contrôle ki effectue un test de parité sur une partie des bits mj du message. Pour
déterminer qui contrôle quoi, il suffit de convertir le numéro de chaque bit en binaire :

Bit n° 4 (k3) 2 (k2) 1 (k1) mj est contrôlé par ↓


1 (k1) 0 0 1 k1
2 (k2) 0 1 0 k2
3 0 1 1 k2 + k 1
4 (k3) 1 0 0 k3
5 1 0 1 k3 + k 1
6 1 1 0 k3 + k 2
7 1 1 1 k3 + k2 + k1
5, 6, 7 3, 6, 7 3, 5, 7 ← ki contrôle les bits

Création d’un code de Hamming (envoi d’un message)


On souhaite protéger d bits de données par un code de Hamming en vue, par exemple, de leur
transmission sur un réseau. Les opérations à réaliser sont les suivantes.

1. Déterminer le nombre k de bits de contrôle nécessaires en fonction du nombre d de bits de


données à protéger, ce qui fournit la longueur totale m du code de Hamming.

2. Établir la structure du message : les k bits de contrôle occupent les positions qui
correspondent aux k premières puissances de 2 (1, 2, 4, 8…), les autres positions sont
occupées par les bits de données.

3. Calculer la valeur de chaque bit de contrôle. Pour déterminer la valeur du bit k1, on compte le
nombre de bits à 1 parmi les bits 3, 5 et 7 du message et on ajuste la valeur de k1 de manière
à obtenir un nombre pair ou impair de 1 en fonction la parité choisie. Idem pour le bit k2 (bits
3, 6 et 7) et le bit k3 (bits 5, 6, 7).

Page 3.32 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Le codage des informations

Exemple : calculer le code de Hamming à parité paire pour protéger la donnée de 4 bits « 1011 ».

Pour protéger 4 bits de données, il faut ajouter 3 bits de contrôle. La longueur totale du code
de Hamming est donc égale à 7 bits. La structure du message est donnée ci-dessous : les bits
de contrôle occupent les positions 1, 2 et 4 (puissances de 2), les 4 bits de données occupent
les 4 autres positions (3, 5, 6 et 7).

7 6 5 4 3 2 1
1 0 1 k3 1 k2 k1

Calcul des 3 bits de contrôle de parité paire :

• k1 (bits 3, 5, 7) : 3 bits à 1 → k1 = 1
• k2 (bits 3, 6, 7) : 2 bits à 1 → k2 = 0
• k3 (bits 5, 6, 7) : 2 bits à 1 → k3 = 0

Le code de Hamming final est donc 1010101.

7 6 5 4 3 2 1
1 0 1 0 1 0 1

Vérification d’un code de Hamming (réception d’un message)


Lors de la réception d’un code de Hamming, le message reçu contient les bits de données ainsi que
les bits de contrôle. Ceux-ci sont disposés selon la structure expliquée ci-devant. Avant d’extraire les
données, il convient de vérifier l’intégrité du code reçu. Si une erreur est détectée, le code de
Hamming permettra de corriger le bit en erreur. Les opérations à réaliser sont les suivantes.

1. Connaissant la longueur totale m du message reçu, déterminer le nombre k de bits de


contrôle et le nombre d = m-k de bits de données.

2. Calculer la valeur de chaque bit de contrôle ki’ sur base du contenu message reçu.

3. Comparer la valeur calculée ki’ avec la valeur du bit ki dans le message reçu. Si les deux
valeurs sont identiques le résultat Ri vaut 0, sinon Ri vaut 1.

4. Le nombre binaire Ri … R2R1 vaut 0 s’il n’y a pas d’erreur. Sinon, sa valeur décimale indique le
numéro du bit en erreur.

Exemple : vérifier si le code de Hamming à parité paire « 1110101 » est correct et récupérer les
données protégées par ce code. [Note : il s’agit du code de Hamming de l’exemple précédent dans
lequel on a modifié le bit 6 de 0 à 1.]

La longueur totale du message étant de 7 bits, il contient 3 bits de contrôle aux positions 1, 2
et 4 (puissances de 2) et par conséquent 4 bits de données aux positions 3, 5, 6 et 7. La
structure du code est la suivante :

7 6 5 4 3 2 1
1 1 1 0 1 0 1
d4 d3 d2 k3 d1 k2 k1

© HELMo Campus Guillemins Page 3.33


Le codage des informations Architecture des ordinateurs - Théorie

Calculons la valeur présumée ki’ de chaque bit de contrôle de parité paire sur la base du
contenu du message reçu et comparons cette valeur à la valeur ki effectivement reçue :
• k1’ (bits 3, 5, 7) : 3 bits à 1 → k1’ = 1 k1 = 1 → correct : R1 = 0
• k2’ (bits 3, 6, 7) : 3 bits à 1 → k2’ = 1 k2 = 0 → erreur : R2 = 1
• k3’ (bits 5, 6, 7) : 3 bits à 1 → k3’ = 1 k3 = 0 → erreur : R3 = 1

Assemblons ces résultats : R3R2R1 = 1102 = 610 → le bit 6 est en erreur !

Pour obtenir les bits de données transmis, nous commençons par corriger le bit 6 qui passe
de 1 à 0, puis nous supprimons les bits de contrôle. La donnée reçue est donc « 1011 »

Méthode rapide pour calculer la valeur des bits de contrôle


1. Identifier les bits de données qui valent 1.
2. Exprimer leurs positions en binaire sur k bits.
3. Calculer la valeur du bit de parité (paire ou impaire) de chaque colonne.

Exemple : protéger la donnée de 11 bits « 01101001101 » avec un code de Hamming à parité paire.

Pour protéger 11 bits de données, il faut utiliser 4 bits de contrôle qui occuperont les
positions 1, 2, 4 et 8. Le message de 15 bits à transmettre est donc de la forme :

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
0 1 1 0 1 0 0 k4 1 1 0 k3 1 k2 k1

Les bits de données à 1 occupent les positions 14, 13, 11, 7, 6 et 3. Pour déterminer la valeur
des 4 bits de contrôle du code de Hamming, il suffit de convertir ces positions en binaire sur
4 bits et de calculer la valeur du bit de parité paire pour chaque colonne.

14 1110
13 1101
11 1011
7 0111
6 0110
3 0011
1 0 1 0 → k4=1, k3=0, k2=1, k1=0 (pour une parité impaire, il faut inverser.)

On obtient le message final :

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
0 1 1 0 1 0 0 1 1 1 0 0 1 1 0

Page 3.34 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Le codage des informations

3.7.4 Détection d’erreurs groupées (CRC)


Dans les transmissions de données sur un réseau, une perturbation momentanée, même très brève,
de la ligne de transmission va entraîner l’apparition d’erreurs sur de nombreux bits consécutifs. On
parle d’erreurs groupées.

Il est difficilement envisageable de corriger automatiquement de telles erreurs. Cependant, il est


fondamental de pouvoir les détecter efficacement et de retransmettre le message si nécessaire.

La technique la plus utilisée est celle du CRC (Cyclic Redundancy Check) ou contrôle de redondance
cyclique.

L’idée générale de cette technique (que nous ne détaillerons pas) est la suivante :

• On considère que le message à transmettre représente un polynôme M(x) (cf. formule de


définition générale des nombres).

Exemple : M(x) = x3 + x1 +x0 = 1011 (degré = 3)

• L’émetteur choisit un autre polynôme (appelé polynôme générateur) de degré r.

Exemple : G(x) = x2 +x0 = 101 (degré = 2)

• Il multiplie le polynôme M(x) par xr, ce qui revient à ajouter r zéros à la fin du message de
départ.

Exemple : (x3 + x1 +x0).x2 = x5 + x3 +x2 = 101100

• Il effectue ensuite la division de M(x).xr par le polynôme générateur, ce qui fournit un


quotient Q(x) et un reste R(x) :

M(x).xr / G(x) → M(x).xr = Q(x).G(x) + R(x) [P = Quotient x Diviseur + Reste]

• Le polynôme transmis T(x) est le résultat de M(x).xr – R(x) (on soustrait le reste).

T(x) = M(x).xr – R(x) = Q(x).G(x)


→ le message transmis est donc un multiple de G(x) !

• Le polynôme T(x) porte le nom de polynôme cyclique.

• A la réception, le message reçu est divisé par le même polynôme générateur G(x).
• Si le reste de la division n’est pas nul, c’est qu’une erreur de transmission s’est produite.

Grâce aux CRC, on peut détecter des erreurs groupées affectant jusqu’à 16 bits consécutifs ou plus !

© HELMo Campus Guillemins Page 3.35


Le codage des informations Architecture des ordinateurs - Théorie

3.8 Compression des données


La compression a pour objectif de réduire la quantité de bits utilisés pour représenter des données.
Cela permet de gagner de l’espace en mémoire ou de réduire le volume des données à transmettre
sur un réseau.

De nombreuses méthodes (algorithmes) de compression existent. Elles se différencient les unes des
autres par les caractéristiques suivantes :

• La qualité de compression – On distinguera les méthodes de compression avec ou sans perte


d’informations.
Un algorithme de compression sans perte est réversible. Il permet de reconstituer les
données de départ sans les altérer (texte, base de données…).
Un algorithme de compression avec perte n’est pas réversible. Les données décompressées
seront proches de celles de départ, mais elles contiendront des altérations plus ou moins
importantes en fonction de la qualité de compression choisie (images, musique…).

• Le taux de compression – C’est le rapport entre la taille des données initiales et la taille des
données compressées. Les algorithmes sans perte arrivent à des taux de compression
moyens de l’ordre de 3:1. Les algorithmes avec perte peuvent atteindre 10:1, voire 100:1.

• Le temps de compression – Indépendamment de la performance du matériel utilisé, le temps


nécessaire pour compresser des données dépend bien sûr du volume de données à
compresser, mais aussi de la complexité de la méthode de compression choisie.
Un algorithme de compression sophistiqué permet d’améliorer le taux de compression ou de
réduire la perte d’informations, voire les deux. En contrepartie, il requiert des calculs plus
complexes et prend donc plus de temps pour s’exécuter.
Si l’objectif prioritaire est de réduire le volume des données (espace de stockage limité,
transmission facturée au volume) ou de conserver une qualité maximale (vidéo en haute
définition), la compression n’est généralement réalisée qu’une seule fois et le temps de
compression est secondaire. Si l’objectif est de réduire le temps nécessaire pour transmettre
des données, il ne faut pas que l’augmentation du temps de compression annule le gain de
temps obtenu lors de la transmission.

Quelques exemples d’algorithmes de compression réversibles connus.

• Usage général: Codage Huffman, Lempel-Ziv-Welsch (LZW), Run Length Encoding (RLE), …
• Audio : Apple Lossless (ALAC), Dolby TrueHD, WMA Lossless, …
• Image : GIF, PNG, TIFF

Quelques exemples d’algorithmes de compression non réversibles connus.

• Audio : MP3, WMA, Ogg Vorbis, …


• Image : JPEG
• Vidéo : motion JPEG, MPEG, H.264, …

Page 3.36 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Les circuits logiques

44 Les circuits logiques


4.1 Algèbre de Boole et portes logiques
4.1.1 Introduction
« L'algèbre de Boole, ou calcul booléen, est la partie des mathématiques, de la logique et de
l'électronique qui s'intéresse aux opérations et aux fonctions sur les variables logiques. Plus
spécifiquement, l'algèbre booléenne permet d'utiliser des techniques algébriques pour traiter les
expressions à deux valeurs du calcul des propositions. Elle fut initiée en 1854 par le mathématicien
britannique George Boole. » (Source : Wikipedia.)

4.1.2 Variables booléennes et fonctions logiques


Une variable booléenne, ou variable logique, est une variable qui peut prendre 2 valeurs distinctes.
Ces 2 valeurs sont désignées par 0 et 1. Dans les langages de programmation, on rencontrera souvent
les valeurs faux (false) et vrai (true).

Une fonction logique associe à une ou plusieurs variables logiques d’entrée un résultat dont la valeur
est elle aussi 0 ou 1. Cette valeur dépend de l’état des variables d’entrée.

On décrit généralement une fonction logique au moyen d’une table de vérité. Cette table indique la
valeur de la fonction logique pour toutes les combinaisons possibles des variables d’entrée.

Pour n variables logiques, le nombre de combinaisons possibles est égal à 2n. Pour chacune de ces
combinaisons, la fonction logique peut prendre deux valeurs possibles (0 ou 1). Il y a donc au total
𝑛
22 fonctions logiques distinctes de n variables, ce qui donne :

• 1 variable : 4 fonctions,
• 2 variables : 16 fonctions,
• 3 variables : 256 fonctions,
• Etc.

© HELMo Campus Guillemins Page 4.1


Les circuits logiques Architecture des ordinateurs - Théorie

La table suivante nous présente les 4 fonctions logiques d’une variable :

a
0 1 f(a)
0 0 0 Constante 0
1 0 1 Identité
2 1 0 Complémentation : 𝑎̅ (NOT)
3 1 1 Constante 1
Table 4.1 - Fonctions logiques d'une variable

Parmi ces différentes fonctions, la seule qui soit vraiment intéressante est la fonction de
complémentation (3ème ligne de la table). On parle d’opérateur NON (NOT) ou encore d’inverseur, car
la fonction inverse la valeur de la variable d’entrée.

Le complément de a est généralement noté 𝑎̅ (qui se lit « non-a » ou « a-barre »).

Avec 2 variables d’entrée, on obtient les 16 fonctions logiques suivantes :

ab
00 01 10 11 f(ab)
0 0 0 0 0 0 (constante)
1 0 0 0 1 𝑎𝑏 (AND)
2 0 0 1 0 𝑎𝑏̅
3 0 0 1 1 𝑎
4 0 1 0 0 𝑎̅𝑏
5 0 1 0 1 𝑏
6 0 1 1 0 𝑎 ⊕ 𝑏 = 𝑎𝑏 + 𝑎𝑏 (XOR)
7 0 1 1 1 𝑎 + 𝑏⁡⁡ (OR)
8 1 0 0 0 ̅̅̅̅̅̅̅
𝑎 + 𝑏 = 𝑎 ↓ 𝑏 (NOR)
9 1 0 0 1 ̅̅̅̅̅̅̅̅
𝑎 ⊕ 𝑏 = 𝑎 ⇔ 𝑏 (XNOR)
10 1 0 1 0 𝑏̅
11 1 0 1 1 𝑎 + 𝑏̅
12 1 1 0 0 𝑎̅
13 1 1 0 1 𝑎̅ + 𝑏
14 1 1 1 0 ̅̅̅ ⁡ = 𝑎 ↑ 𝑏 (NAND)
𝑎𝑏
15 1 1 1 1 1 (constante)
Table 4.2 - Fonctions logiques de deux variables

Page 4.2 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Les circuits logiques

4.1.3 Opérateurs logiques et portes logiques


Certaines fonctions jouent un rôle privilégié en algèbre booléenne, car elles permettent d’exprimer
aisément toutes les autres. Ces fonctions portent le nom d’opérateurs logiques. À chaque opérateur
logique correspond un circuit logique élémentaire appelé porte logique (gate). Les portes logiques
sont des composants très simples construits à partir de quelques transistors. Elles constituent les
blocs de base qui servent à construire tous les ordinateurs digitaux.

Certains circuits électroniques travaillent en logique positive, c’est-à-dire qu’une tension de 0 volt
correspond à la valeur logique 0 et une tension positive (par exemple 1,5 volt) correspond à la valeur
logique 1. D’autres travaillent en logique négative, c’est-à-dire que 0 volt représente la valeur logique
1 et 1,5 volt représente la valeur logique 0. Sauf mention contraire explicite, nous utiliserons toujours
une logique positive.

Nous donnons ci-après les tables de vérité, les noms (français et anglais) et les symboles des
principaux opérateurs logiques. Dans ce syllabus, nous utiliserons indifféremment les noms français
et anglais.

Il convient de signaler que l’opérateur logique ET/AND est soit représenté par un point ‘.’, soit omis
s’il n’y a pas de confusion possible, ainsi : « abc = a.b.c = ab.c = a.bc ».

NON / NOT

a not
0 1 a a
1 0 NOT

ET / AND

a b and
0 0 0 a ab
0 1 0 b
1 0 0 AND
1 1 1

OU / OR

a b or
0 0 0 a
0 1 1 a+b
b
1 0 1 OR
1 1 1

© HELMo Campus Guillemins Page 4.3


Les circuits logiques Architecture des ordinateurs - Théorie

OU EXCLUSIF / XOR

a b xor
0 0 0 a
0 1 1 a⊕b
b
1 0 1
XOR
1 1 0

NON-ET / NAND

a b nand
0 0 1
0 1 1
a ab = a b
1 0 1 b
1 1 0 NAND

NON-OU / NOR

a b nor
0 0 1
a
0 1 0 a+b = a b
1 0 0 b
1 1 0 NOR

NON-OU EXCLUSIF / XNOR (équivalence)

a b xnor
0 0 1 a
0 1 0 a b
1 0 0 b
1 1 1 XNOR

4.1.4 Implémentation physique des fonctions logiques


Il existe différentes façons de construire des circuits électriques ou électroniques qui implémentent
des fonctions logiques.

On peut par exemple réaliser les fonctions ET et OU en plaçant des interrupteurs électriques
respectivement en série ou en parallèle, comme illustré ci-dessous.

ET OU

Page 4.4 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Les circuits logiques

Dans le circuit de gauche, la lampe s’allume uniquement si les deux interrupteurs sont fermés (ET).
Dans le circuit de droite, la lampe s’allume si au moins un des deux interrupteurs est fermé (OU).

Les portes logiques des circuits électroniques sont quant à elles généralement construites à partir
d’un composant de base appelé transistor. Un transistor fonctionne essentiellement comme un
interrupteur. Le schéma suivant illustre son fonctionnement.

Si la tension d’entrée E à la base du transistor est inférieure à une valeur


Vcc de seuil prédéfinie (0 logique), le transistor n’est pas conducteur et se
comporte comme un interrupteur ouvert. La tension de sortie S est à un
E niveau bas proche de la masse (0 logique).
S
Si la tension d’entrée E est supérieure la valeur de seuil (1 logique), le
transistor devient conducteur et se comporte comme un interrupteur
fermé. La tension de sortie S est proche de la tension de fonctionnement
Figure 4-1 - Transistor
Vcc, c’est-à-dire à un niveau haut (1 logique). La résistance permet de
limiter le courant qui circule dans le transistor.

Si on déplace le point de sortie et la résistance en amont du transistor, on obtient un inverseur, c’est-


à-dire une porte logique NOT.

Lorsque la tension appliquée à la base est à un niveau bas (0 logique), le


Vcc transistor n’est pas conducteur (ouvert) et la tension de sortie est proche
de la tension de fonctionnement Vcc, c’est-à-dire à un niveau haut (1
a logique).
a Si on contraire, la tension appliquée à la base est à un niveau haut (1
logique), le transistor est conducteur (fermé) et la tension de sortie S passe
à un niveau bas proche de la masse (0 logique).
Figure 4-2 - Inverseur
La tension de sortie est donc bien l’inverse de celle d’entrée.

Le tableau ci-dessous illustre la manière de créer des portes logiques AND, OR, NAND et NOR avec
des transistors. Comme dans le cas des circuits électriques qui utilisent des interrupteurs, on
retrouve un montage en série pour réaliser une porte AND et un montage en parallèle pour réaliser
une porte OR. Les portes NAND et NOR diffèrent juste par le fait qu’on a déplacé le point de sortie et
la résistance en amont des transistors, comme dans le cas de l’inverseur.

AND OR NAND NOR


Vcc Vcc Vcc Vcc
a a
ab a+b
b b a a
ab a+b
b b

Figure 4-3 - Portes logiques avec des transistors

© HELMo Campus Guillemins Page 4.5


Les circuits logiques Architecture des ordinateurs - Théorie

4.1.5 Propriétés et théorèmes fondamentaux de l’algèbre de


Boole
Nous rappelons dans le tableau ci-dessous les principales règles de l’algèbre de Boole sans les
démontrer (cf. cours de mathématiques).

Nom Forme OU Forme ET


Neutre 𝑎⁡ + ⁡0⁡ = ⁡𝑎 𝑎⁡. 1⁡ = ⁡𝑎
Constante 𝑎⁡ + ⁡1⁡ = ⁡1 𝑎⁡. 0⁡ = ⁡0
Idempotence 𝑎+𝑎 =𝑎 𝑎𝑎⁡ = ⁡𝑎
Complémentation 𝑎 + 𝑎̅ = 1 𝑎𝑎̅ = 0
Commutativité 𝑎+𝑏 =𝑏+𝑎 𝑎𝑏 = 𝑏𝑎
Associativité (𝑎 + 𝑏) + 𝑐 = 𝑎 + (𝑏 + 𝑐) = 𝑎 + 𝑏 + 𝑐 (𝑎𝑏)𝑐 = 𝑎(𝑏𝑐) = abc
Distributivité 𝑎(𝑏 + 𝑐) = 𝑎𝑏 + 𝑎𝑐 𝑎 + (𝑏𝑐) = (𝑎 + 𝑏)(𝑎 + 𝑐)
Absorption 𝑎 + 𝑎𝑏⁡ = ⁡𝑎 𝑎(𝑎 + 𝑏) = 𝑎
Th. de De Morgan ̅̅̅̅̅̅̅
𝑎 + 𝑏 = 𝑎̅. 𝑏̅ ̅̅̅ = 𝑎̅ + 𝑏̅
𝑎𝑏
Table 4.3 - Propriétés et théorèmes fondamentaux de l'algèbre de Boole

4.1.6 Formes normales


Toute fonction logique peut s’exprimer en utilisant uniquement les opérateurs ET, OU et NON.

Étant donné une fonction logique de n variables, on appelle minterme un produit logique (ET) où ces
n variables apparaissent soit sous leur forme directe (𝑎), soit sous leur forme complémentée (𝑎̅). De
même, on appelle maxterme une somme logique (OU) de ces n variables.

Partant de la table de vérité d’une fonction logique, il est possible de formuler algébriquement cette
fonction sous deux formes particulières appelées formes normales.

La première forme normale (disjonctive) :

• Somme logique (OU) des mintermes (produits logiques - ET) correspondant aux lignes de la
table de vérité pour lesquelles la fonction vaut 1.
• Dans l’expression d’un minterme, une variable d’entrée est complémentée si sa valeur est 0.

Exemple : « ou exclusif » (XOR) en première forme normale

a b xor a ab
0 0 0 𝑎⊕𝑏 b
0 1 1 a⊕b
1 0 1 𝐹𝑁1 = 𝑎̅𝑏 + 𝑎𝑏̅
1 1 0
ab

L’interprétation de la première forme normale est assez intuitive. Le XOR vaut 1 si a=0 et b=1 (𝑎̅𝑏 est
vrai) OU si a=1 et b=0 (𝑎𝑏̅ est vrai), c’est-à-dire 𝑎̅𝑏 + 𝑎𝑏̅.

Page 4.6 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Les circuits logiques

La deuxième forme normale (conjonctive) :

• Produit logique (ET) des maxtermes (sommes logiques - OU) correspondant aux lignes de la
table de vérité pour lesquelles la fonction vaut 0.
• Dans l’expression d’un maxterme, une variable d’entrée est complémentée si sa valeur est 1.

Les règles à appliquer pour obtenir la deuxième forme normale correspondent à « l’inverse » de
celles de la première forme normale : opérateurs ET ↔ OU, lignes 0 ↔ 1, variables 𝑎 ↔ 𝑎.

Exemple : « ou exclusif » (XOR) en deuxième forme normale

a b xor a a+b
0 0 0 𝑎⊕𝑏 b
0 1 1 a b
1 0 1 𝐹𝑁2 = (𝑎 + 𝑏)(𝑎̅ + 𝑏̅)
1 1 0
a+b

La deuxième forme normale, bien qu’a priori moins évidente à interpréter, s’explique grâce au
théorème de De Morgan. En effet, le XOR vaut 0 si a=0 et b=0 (𝑎𝑏 est vrai) OU si a=1 et b=1 (𝑎𝑏 est
vrai), c’est-à-dire 𝑎𝑏 + 𝑎𝑏. Donc, le XOR vaut 1 si on prend la négation de cette formule.
En appliquant le théorème de De Morgan, obtient la deuxième forme normale :
𝑎 ⊕ 𝑏 = (𝑎𝑏 + 𝑎𝑏) = (𝑎𝑏). (𝑎𝑏) = (𝑎 + 𝑏)(𝑎̅ + 𝑏̅) = (𝑎 + 𝑏)(𝑎̅ + 𝑏̅)

4.1.7 Synthèse d’un circuit logique à partir d’une table de


vérité
Il existe une méthode très simple pour concevoir un circuit logique qui correspond à une fonction
logique dont on connaît la table de vérité. On commence par exprimer la fonction dans une des deux
formes normales vues précédemment : somme de mintermes ou produit de maxtermes.

Pour la première forme normale :

• Chaque minterme est réalisé par une porte logique ET à laquelle sont raccordés les n signaux
d’entrée de la fonction, éventuellement complémentés.
• Les sorties de ces portes ET sont combinées au moyen d’une porte logique OU afin de
réaliser la somme des mintermes.

Pour la deuxième forme normale :

• Chaque maxterme est réalisé par une porte logique OU à laquelle sont raccordés les n
signaux d’entrée de la fonction, éventuellement complémentés.
• Les sorties de ces portes OU sont combinées au moyen d’une porte logique ET afin de
réaliser le produit des maxtermes.

© HELMo Campus Guillemins Page 4.7


Les circuits logiques Architecture des ordinateurs - Théorie

Exemple : la fonction majorité

Nous souhaitons créer un circuit logique composé exclusivement de portes {NON, ET, OU} qui
réalise la fonction logique de 3 variables décrite par la table de vérité suivante.

a b c MAJ
0 0 0 0
0 0 1 0
0 1 0 0
0 1 1 1
1 0 0 0
1 0 1 1
1 1 0 1
1 1 1 1

Il s’agit de la fonction « majorité », car sa valeur vaut 1 lorsqu’une majorité des 3 variables
d’entrée valent 1.

Les deux formes normales de cette fonction sont :

1. 𝑚𝑎𝑗(𝑎, 𝑏, 𝑐) = ⁡ 𝑎̅𝑏𝑐 + 𝑎𝑏̅𝑐 + 𝑎𝑏𝑐̅ + 𝑎𝑏𝑐


2. 𝑚𝑎𝑗(𝑎, 𝑏, 𝑐) = (𝑎 + 𝑏 + 𝑐)(𝑎 + 𝑏 + 𝑐̅)(𝑎 + 𝑏̅ + 𝑐)(𝑎̅ + 𝑏 + 𝑐)

Les schémas logiques des circuits correspondant à ces 2 formes normales sont présentés ci-
après. À gauche, celui qui correspond à la première forme normale (somme de mintermes). À
droite, celui qui correspond à la deuxième forme normale (produit de maxtermes).

ABC ABC ABC ABC

ABC A+B+C

A A

ABC A+B+C

B B
MAJ MAJ

ABC A+B+C
C C

ABC A+B+C

La technique de synthèse d’un circuit logique présentée dans l’exemple précédent est très facile à
mettre en œuvre et facilement généralisable à n variables.

En revanche, elle ne conduit pas nécessairement au circuit logique qui utilise le moins de portes
logiques. Ainsi, si on applique la méthode de simplification de Karnaugh (cf. cours de
mathématiques) à la fonction majorité, on obtient :

𝑚𝑎𝑗(𝑎, 𝑏, 𝑐) = 𝑎𝑏 + 𝑎𝑐 + 𝑏𝑐

La mise en œuvre de cette forme simplifiée ne nécessite que 3 portes ET à 2 entrées et une porte OU
à 3 entrées.

Page 4.8 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Les circuits logiques

4.1.8 NAND et NOR : opérateurs complets


Nous avons vu qu’il est possible d’exprimer n’importe quelle fonction logique sous une forme
normale. Une telle forme normale utilise uniquement les 3 opérateurs logiques {NON, ET, OU}.
Cet ensemble n’est toutefois pas minimal.

En effet, le théorème de De Morgan nous montre qu’il est possible d’exprimer la fonction ET avec les
opérateurs {OU, NON}, ou d’exprimer la fonction OU avec les opérateurs {ET, NON}. Nous pouvons
donc exprimer toute fonction logique avec seulement besoin de 2 opérateurs logiques.

Nous pouvons aller encore plus loin et montrer que les opérateurs ET, OU, NON peuvent à leur tour
être exprimés grâce à un seul opérateur : soit NAND, soit NOR.
Les opérateurs NAND et NOR sont appelés opérateurs complets, car chacun d’eux permet de générer
tous les autres opérateurs logiques, comme illustré dans le tableau ci-dessous.

a ab = a b a
a+b = a b
b b
NAND NOR

NON ET OU

a a
a a ab a+b
NOT
b b
AND OR

a
a
a a ab a+b
b
b

𝑎 ↑ 𝑎 = 𝑎⁡. 𝑎 = 𝑎 𝑎𝑏 = 𝑎⁡. 𝑏 = 𝑎 ↑ 𝑏 𝑎 + 𝑏 = 𝑎 + 𝑏 = 𝑎. 𝑏 = 𝑎 ↑ 𝑏

a
a a a a+b
ab
b
b

𝑎 ↓𝑎 = 𝑎+𝑎 = 𝑎 𝑎𝑏 = 𝑎⁡. 𝑏 = 𝑎 + 𝑏 = 𝑎 ↓ 𝑏 𝑎+𝑏 =𝑎+𝑏 =𝑎 ↓𝑏

Figure 4-4 - Les opérateurs complets NAND et NOR

© HELMo Campus Guillemins Page 4.9


Les circuits logiques Architecture des ordinateurs - Théorie

4.2 Circuits combinatoires


4.2.1 Définition
Un circuit combinatoire est un circuit logique possédant un certain nombre d’entrées et de sorties,
pour lequel la valeur des sorties à un instant donné est uniquement déterminée par la valeur des
entrées à cet instant.

C’est par exemple le cas pour un circuit qui implémente une fonction logique définie par une table de
vérité. Tous les circuits illustrés précédemment dans ce syllabus présentent cette caractéristique et
sont donc des circuits combinatoires.

Il existe toutefois des circuits qui n’ont pas cette caractéristique. Considérons un circuit mémoire : sa
valeur de sortie dépend bien évidemment de l’adresse mémoire demandée (entrée), mais elle
dépend surtout de la valeur qui a été précédemment stockée à cette adresse (historique du circuit).
Pour une même adresse (entrée), nous obtiendrons des valeurs différentes (sortie) au fil du temps.

Intéressons-nous à présent à quelques circuits combinatoires essentiels pour construire un


ordinateur.

4.2.2 Décodeur
Un décodeur est un circuit combinatoire dont la caractéristique est d’activer une de ses 2n sorties (S0,
S1, …) en fonction de la valeur du code appliqué à ses n lignes de commande (A, B, …). On parlera
ainsi de décodeur « 1 vers 2 » (code de 1 bit), « 2 vers 4 » (code de 2 bits), « 3 vers 8 » (code de 3
bits), etc.

Le schéma logique interne d’un décodeur est assez simple à comprendre :


• chaque sortie du circuit correspond à une porte ET à n entrées ;
• les entrées des différentes portes ET sont câblées de manière à calculer chacune des 2n
combinaisons possibles des n lignes de commande.

DECODER
AB

00 S0
AB

01 S1
AB
10 S2

AB
11 S3

A B A B

Figure 4-5 - Circuit décodeur « 2 vers 4 »

Page 4.10 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Les circuits logiques

Fonctionnement : si la sortie S1 doit valoir 1 pour le code de sélection 𝐴𝐵 = 01 (1 en binaire sur 2


bits), il suffit de câbler ses entrées sur 𝐴 et 𝐵. En effet, si 𝐴𝐵 = 01 alors 𝑆1 = 𝐴⁡. 𝐵 = 1.1 = 1.

Nous verrons qu’un circuit décodeur a de multiples usages dans un ordinateur. Il peut par exemple
être utilisé dans une unité arithmétique et logique pour sélectionner l’opération à réaliser parmi 2n
opérations possibles, sur base de n bits présents dans l’instruction à exécuter. Il permet également
de décoder une adresse de 32 bits pour aller chercher une donnée dans une mémoire de 4 GB (232).

4.2.3 Multiplexeur
4.2.3.1 Fonctionnement
Un multiplexeur est un circuit dont le rôle consiste à aiguiller le signal appliqué à l’une de ses
multiples entrées de données vers son unique sortie. La ligne de donnée à sélectionner est
déterminée par les signaux appliqués aux entrées de commande.

Un multiplexeur qui comporte n entrées de commande (A, B, …) et capable d’effectuer un choix


parmi 2n entrées de données (D0, D1, …). On parlera ainsi de multiplexeur « 2 vers 1 » (1 bit de
sélection), « 4 vers 1 » (2 bits de sélection), « 8 vers 1 » (3 bits de sélection), etc.

Le schéma interne du multiplexeur illustré à la figure ci-dessous est assez proche de celui du
décodeur. On y retrouve notamment le principe d’activation (partielle) d’une porte ET en fonction du
code appliqué aux lignes de commande. Deux éléments viennent s’ajouter :

• chaque entrée de données Dx vient se connecter sur la porte ET qui correspond au code de
sélection AB = x ;
• une porte OU combine les sorties des portes ET pour calculer la valeur de l’unique sortie du
circuit.

D0 D0AB MUX

D0 00
D1 D1AB

S
D1 01
D2
S
D2AB D2 10

D3 D3 11
D3AB

A B A B

Figure 4-6 - Circuit multiplexeur « 4 vers 1 »

© HELMo Campus Guillemins Page 4.11


Les circuits logiques Architecture des ordinateurs - Théorie

Fonctionnement : si on applique un code AB à l’entrée de commande du multiplexeur représenté ci-


dessus, une seule des 4 portes ET sera « activée » par ce code. La sortie de cette porte ET et par
conséquent celle du circuit multiplexeur sera égale à la donnée présente à l’entrée de données
sélectionnée.

Exemple

Si le code AB = 10 est appliqué en commande, la troisième porte ET en partant du haut est


pré-activée, car c’est la seule porte dont les deux entrées inférieures valent 1 (𝐴𝐵 = 10 →
𝐴𝐵 = 11). La sortie de cette porte ET sera égale à la valeur de D2 puisque 𝐷2⁡ . 1⁡. 1 = 𝐷2. La
valeur de sortie des trois autres portes ET vaut 0, car moins une des trois entrées vaut 0.

La porte OU en sortie du circuit calcule le résultat final :⁡𝑆 = 0 + 0 + 𝐷2 + 0 = 𝐷2.

4.2.3.2 Fonction universelle


On peut utiliser un multiplexeur à n entrées de commande pour calculer n’importe quelle fonction
logique de n variables.

Pour implémenter une fonction logique à 2 variables, on choisira un multiplexeur « 4 vers 1 » avec 2
bits de commande. Pour 3 variables, on choisira un multiplexeur « 8 vers 1 » avec 3 bits de
commande. Etc.

On câble ensuite chaque entrée de données Dx en fonction de la valeur de la table de vérité pour la
combinaison ab = x :

• si la table de vérité a pour valeur 1, l’entrée Dx est raccordée à la tension de fonctionnement


positive Vcc (valeur logique 1) ;
• si la table de vérité a pour valeur 0, l’entrée Dx est raccordée à la terre (valeur logique 0).

Exemple : la fonction XOR


VCC

D0
a b xor Dx
0 0 0 D0
D1
0 1 1 D1
A⊕B
1 0 1 D2
D2
1 1 0 D3
D3

A B

Un multiplexeur est un circuit combinatoire qui implémente une fonction universelle.

Page 4.12 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Les circuits logiques

4.2.4 Démultiplexeur
Un démultiplexeur réalise l’inverse d’un multiplexeur.

Il possède une seule ligne d’entrée de données (E) qui est aiguillée vers une des 2n sorties (S0, S1, …)
en fonction de la valeur sélectionnée par les n lignes de commande (A, B, …).

Le schéma interne du multiplexeur illustré à la figure ci-dessous est quasiment identique à celui du
décodeur :

• on y retrouve le principe d’activation (partielle) d’une porte ET en fonction du code appliqué


aux lignes de commande ;
• la seule différence provient du fait que l’entrée de données E est connectée à chacune des
portes ET.

EAB DEMUX

00 S0
EAB

E 01 S1
E
EAB
10 S2

EAB
11 S3

A B A B

Figure 4-7 - Circuit démultiplexeur « 1 vers 4 »

Fonctionnement : en fonction du code AB de commande, une seule porte ET de sortie est pré-
activée. Sa valeur de sortie est alors égale à 𝐸. 1⁡. 1 = 𝐸. La valeur de sortie des trois autres portes ET
vaut 0.

Un décodeur est un cas particulier de démultiplexeur dont le signal d’entrée E vaut toujours 1

4.2.5 Comparateur
Un comparateur est un circuit combinatoire qui permet de comparer l’égalité entre 2 nombres
appliqués en entrée. Sa sortie vaut 1 si les 2 nombres sont égaux et 0 s’ils diffèrent.

Exercice : concevoir un circuit logique qui teste l’égalité de deux nombres de 4 bits.

Suggestion : commencez par concevoir un circuit logique qui compare 2 nombres de 1 bit,
puis généralisez la solution à 2, 3, 4 bits ou plus.

© HELMo Campus Guillemins Page 4.13


Les circuits logiques Architecture des ordinateurs - Théorie

4.2.6 Additionneur
L’opération arithmétique binaire la plus élémentaire est l’addition.

Dans un premier temps, nous allons limiter notre ambition à l’addition de deux nombres a et b
exprimés sur 1 bit. Nous pouvons spécifier le résultat de l’addition binaire de deux nombres de 1 bit
au moyen de la table de vérité suivante :

a b S R
0 0 0 0
0 1 1 0
1 0 1 0
1 1 0 1
xor and

S est la somme binaire et R la retenue éventuelle (« carry » en anglais). On voit que la somme est le
résultat de l’opération logique 𝑎 ⊕ 𝑏 (XOR), tandis que la retenue est le résultat de l’opération
logique 𝑎𝑏 (AND).

On obtient donc le circuit suivant :

a
S = a⊕b
b

R = ab

Figure 4-8 - Demi-additionneur

Un tel circuit est appelé demi-additionneur. En effet, il peut générer un bit de retenue résultant de
l’addition de a et b, mais il ne tient pas compte d’une retenue précédente éventuelle.

Pour cela, nous avons besoin d’un additionneur complet.

retenue précédente
R
S
a
b
retenue
propagée
R
retenue générée

Figure 4-9 - Additionneur complet

L’additionneur complet est composé de deux demi-additionneurs et d’une porte OU.

La somme S est obtenue en effectuant l’opération arithmétique « (𝑎 + 𝑏) + ⁡𝑅 », c’est-à-dire


l’opération logique « (𝑎 ⊕ 𝑏) ⊕ 𝑅 ». Il s’agit de la moitié supérieure du circuit (les 2 portes XOR).

Page 4.14 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Les circuits logiques

Il y a une retenue finale R’ quand l’un ou l’autre des cas suivants survient :

1. a et b valent tous les deux 1 → retenue générée par le premier demi-additionneur,


2. il y a une retenue précédente (R=1) et soit 𝑎 soit 𝑏 vaut 1 → retenue propagée par le
deuxième additionneur.

Le calcul de la retenue finale est effectué par la moitié inférieure du circuit (2 portes ET + porte OU).

On peut représenter un additionneur complet par le schéma bloc suivant, qui masque les détails de
son implémentation.

data

add
Rout Rin
sum

Figure 4-10 - Schéma bloc d’un additionneur complet

Pour réaliser une addition sur n bits, il suffit de mettre en parallèle n additionneurs complets sur 1
bit. On connecte la sortie R’ d’un additionneur à l’entrée R de l’additionneur suivant.

a7 b 7 a2 b2 a1 b1 a0 b0

add add add add


R’ R ... R’ R R’ R R’ R

s7 s2 s1 s0

Figure 4-11 - Additionneur sur n bits

Cette approche très simple présente néanmoins un inconvénient majeur : pour obtenir le résultat de
l’addition, il faut attendre que la retenue se propage de proche en proche. On parle d’ailleurs
d’additionneur à propagation de retenue (« ripple-carry adder »). Cette propagation introduit un
délai qui devient vite pénalisant si le nombre de bits à additionner est grand. Dans la pratique, les
ordinateurs utilisent des additionneurs plus complexes et plus rapides. Un exemple d’une
amélioration possible est l’additionneur à retenue anticipée (« carry look-ahead adder »)3.

On peut représenter un additionneur sur 8 bits au moyen du schéma bloc simplifié suivant :

A Input B Input
8 8
a7...a1a0 b7...b 1b0
Carry out 8-bits adder Carry in
s7...s 1s0
8
Sum
Figure 4-12 - Schéma bloc d'un additionneur sur 8 bits

3
Voir par exemple : https://en.wikipedia.org/wiki/Carry-lookahead_adder.

© HELMo Campus Guillemins Page 4.15


Les circuits logiques Architecture des ordinateurs - Théorie

4.3 Unité arithmétique et logique (ALU)


Dans les sections précédentes, nous avons présenté différents circuits combinatoires qui permettent
de réaliser des opérations logiques (ET, OU, NON, …), des opérations arithmétiques (addition), ainsi
que des opérations de sélection diverses (multiplexeur, démultiplexeur, décodeur).

Nous disposons à présent de tous les éléments nécessaires pour construire une unité arithmétique et
logique (ALU) simplifiée. Notre objectif est de concevoir un circuit logique qui pourra réaliser au choix
une des quatre opérations suivantes : ET, OU, NON, addition.

Dans un premier temps, nous considérons une ALU permettant de traiter des données sur 1 bit.

Le schéma logique détaillé ci-dessous présente une organisation possible d’une telle ALU. En
analysant ce circuit, nous pouvons constater qu’il est essentiellement composé de 3 zones
(entourées par des pointillées) : une unité logique qui réalise les opérations logiques (𝐴𝐵, 𝐴 + 𝐵, 𝐵),
une unité arithmétique composée d’un additionneur complet et un décodeur qui sélectionne
l’opération à réaliser en fonction d’un code d’opération (opcode) « F0F1 ».

AB

A+B
S

Unité logique

A
Somme
B

Décodeur

Additionneur

F0 F1 R’

Figure 4-13 - Unité arithmétique et logique simplifiée

Page 4.16 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Les circuits logiques

Le principe de cette ALU est relativement simple :

• Les entrées A et B fournissent les données à traiter.


• Les 2 entrées F0 et F1 donnent le code de l’opération à réaliser parmi 4 (22) :
• 00 = 𝐴⁡𝑎𝑛𝑑⁡𝐵 (ET)
• 01 = 𝐴⁡𝑜𝑟⁡𝐵 (OU)
• 10 = 𝐵̅ (NON)
• 11 = 𝐴 + 𝐵 (somme)
• La sortie S fournit le résultat de l’opération demandée.
• L’entrée R fournit la retenue d’entrée dans le cas d’une addition.
• La sortie R’ fournit la retenue de sortie dans le cas d’une addition.

En y regardant de plus près, on constate que L’ALU réalise simultanément les 4 opérations possibles
sur A et B. En fonction du code de l’opération choisie, le décodeur va activer la porte ET située à la
sortie du morceau de circuit adéquat et donc aiguiller le résultat de l’opération choisie vers la sortie
de l’ALU. Dans le cas d’une addition, le décodeur active également la sortie R’.

Chaque opération logique ou arithmétique est réalisée par une partie spécialisée de l’ALU. Dans
notre exemple très simple, les opérations logiques sont obtenues au moyen de simples portes
logiques, l’addition est quant à elle réalisée au moyen de l’additionneur complet présenté
précédemment.

Comme nous l’avons fait dans le cas d’un additionneur sur n bits, il est possible de connecter entre-
elles n ALU sur 1 bit pour obtenir une ALU sur n bits (8, 16, 32, 64 bits).

A0 B 0 A1 B 1 A 2 B2 A 3 B3

A B A B A B A B

ALU 1 bit ALU 1 bit ALU 1 bit ALU 1 bit


00 = A and B 00 = A and B 00 = A and B 00 = A and B
R R 01 = A or B R’ R 01 = A or B R’ R 01 = A or B R’ R 01 = A or B R’ R’
10 = not B 10 = not B 10 = not B 10 = not B
11 = ADD(A,B) 11 = ADD(A,B) 11 = ADD(A,B) 11 = ADD(A,B)
F0 F1 S F0 F1 S F0 F1 S F0 F1 S
F0
F1
S0 S1 S2 S3

Figure 4-14 - ALU sur 4 bits

Notre unité arithmétique et logique de base peut bien entendu être complétée de manière à
proposer d’autres opérations : XOR, multiplication, division, calculs en virgules flottantes, etc.

L’organisation générale reste la même : il y aura davantage de circuits de calcul et un décodeur plus
important (3 bits = 8 opérations, 4 bits = 16 opérations, …).

© HELMo Campus Guillemins Page 4.17


Les circuits logiques Architecture des ordinateurs - Théorie

4.4 Circuits asynchrones et synchrones


4.4.1 Introduction
Lorsque nous avons construit un additionneur à n bits en chaînant n additionneurs à 1 bit, nous
avons signalé le fait que le signal de retenue (carry) met un certain temps à se propager d’un
additionneur au suivant, ce qui induit un délai éventuellement important pour obtenir le résultat
final de l’addition.

D’une manière générale, quel que soit le circuit électronique, il s’écoule toujours un certain laps de
temps entre le moment où l’on applique des signaux à l’entrée du circuit et celui auquel une réponse
stable est disponible en sortie. Ce délai est lié à la vitesse de propagation des signaux électriques, de
changement d’état des composants électroniques, etc.

Plutôt que de laisser les signaux se propager librement d’un composant à l’autre, il peut être
souhaitable de contrôler l’ordre dans lequel les événements se produisent au sein d’un circuit
électronique et à quel moment un changement d’état survient.

4.4.2 Horloge
Pour cadencer les opérations au sein d’un circuit électronique, on utilisera un signal spécial appelé
signal d’horloge. Ce signal sert à synchroniser le fonctionnement des composants électroniques sur
une référence de temps.

Dans le cadre des circuits électroniques, une horloge est un circuit électronique particulier de type
oscillateur, qui génère un signal composé d’impulsions de largeur fixe et espacées de manière
régulière.

cycle d’horloge (période)

Figure 4-15 - Signal d'horloge

La fréquence des impulsions est appelée fréquence d’horloge (clock frequency). Le temps qui sépare
deux impulsions (= inverse de la fréquence ou période) est appelé cycle d’horloge (clock cycle time).

Ainsi, une horloge qui fonctionne à une fréquence de 2 GHz (Giga Hertz) génère 2 milliards
d’impulsions par seconde, soit une impulsion toutes les 5x10-10 secondes (0,5 nanoseconde).

Page 4.18 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Les circuits logiques

4.4.3 Circuit asynchrone


On dit qu’un circuit est asynchrone (c’est-à-dire non synchronisé) lorsque les signaux se propagent
librement dans le circuit.

La sortie d’un circuit asynchrone est évaluée (modifiée) dès l’instant où les signaux d’entrée sont
appliqués. Il peut néanmoins s’écouler un certain temps avant que la valeur de sortie soit stable.

4.4.4 Circuit synchrone


On dit qu’un circuit est synchrone (c’est-à-dire synchronisé) si son fonctionnement est contrôlé par
un signal d’horloge.

Un circuit électronique synchrone possède toujours une entrée pour le signal d’horloge. Cette entrée
est souvent identifiée par la mention « clock » ou « clk » ou « ck ».

En fonction du circuit, le signal d’horloge peut servir à indiquer :

• à quel moment le circuit prend en considération les signaux d’entrée ;


• à quel moment le circuit peut modifier sa valeur de sortie.

La modification d’état du circuit peut intervenir à 4 moments distincts :

actif inactif
t1 t2 t3

Figure 4-16 - Synchronisation sur un signal d'horloge

1. Lors de la transition montante du signal d’horloge. t1


2. Lorsque le signal d’horloge est actif. ]t1, t2[
3. Lors de la transition descendante du signal d’horloge. t2
4. Lorsque le signal d’horloge est inactif. ]t2, t3[

Un symbole spécifique indique à quel moment la transition survient pour un composant donné :
(1) transition montante, (2) signal actif, (3) transition descendante, (4) signal inactif.

D Q D Q D Q D Q

Clk Clk Clk Clk

(1) (2) (3) (4)

Figure 4-17 - Variantes de bascules D synchrones

© HELMo Campus Guillemins Page 4.19


Les circuits logiques Architecture des ordinateurs - Théorie

4.5 Circuits séquentiels


4.5.1 Définition
Les circuits que nous avons étudiés jusqu’à présent sont tous de type combinatoire. La valeur des
signaux de sortie ne dépend que de la valeur des signaux d’entrée au même instant. De plus, il n’y a
pas de boucle de rétroaction (feedback), c’est-à-dire qu’aucun signal de sortie du circuit n’est
raccordé « en boucle » à une entrée du même circuit.

Un circuit séquentiel est un circuit dans lequel la valeur des signaux de sortie à un instant donné ne
dépend pas uniquement des valeurs d’entrée du circuit à cet instant, mais également de l’historique
du circuit, c’est-à-dire de la séquence des transitions réalisées précédemment par ce circuit. Ce
résultat est obtenu par l’utilisation de boucles de rétroaction dans le circuit.

L’état d’un circuit séquentiel dépend donc de ses entrées, mais aussi de ses états précédents. Il
possède une mémoire du passé.

Remarque importante !

Un circuit séquentiel peut fonctionner de manière synchrone ou asynchrone.


Un circuit combinatoire peut également fonctionner de manière synchrone ou asynchrone.

Le caractère synchrone/asynchrone d’un circuit dépend uniquement de la présence/absence d’une


horloge qui régule son fonctionnement.

Le caractère combinatoire/séquentiel d’un circuit dépend quant à lui de l’absence/présence de


boucles de rétroaction qui vont induire un « effet mémoire » dans le circuit.

4.5.2 Bascules et verrous


Il existe de très nombreux types de bascules. Dans le cadre de ce cours, nous nous intéresserons
uniquement aux bascules de type SR (Set-Reset) et D (Delay ou Data).

Nous allons voir qu’une bascule est un circuit séquentiel élémentaire qui possède deux états stables
(circuit bistable) et qui peut servir à réaliser une mémoire de 1 bit.

Au niveau du vocabulaire, les puristes parlent de :

• bascule (flip-flop) dans le cas d’un circuit synchrone dont le changement d’état intervient lors
d’une transition du signal d’horloge (front montant ou descendant) ;
• verrou (latch) dans le cas
o d’un circuit synchrone dont le changement d’état est conditionné par le niveau du
signal d’horloge (haut ou bas),
o ou lorsque le circuit est asynchrone.

Nous parlerons quant à nous de bascule dans tous les cas de figure.

Page 4.20 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Les circuits logiques

4.5.3 Bascule SR
4.5.3.1 Introduction
Une bascule SR (Set/Reset) est construite à partir de 2 portes NOR (ou 2 portes NAND) dont chaque
sortie est connectée à une entrée de l’autre porte.

Nous rappelons ci-dessous la table de vérité de la fonction NOR et nous donnons la représentation
du circuit d’une bascule SR et de ses deux états stables.

a b nor S
0
1 S
0
0
Q Q
0 0 1 0 1

0 1 0 1 0
1 0 0 0
Q 1
Q
R 0 R 0
1 1 0

Ce circuit comporte 2 entrées (S et R) et 2 sorties (𝑄 et 𝑄̅ ) :

• l’entrée S (Set) est utilisée pour mettre la bascule dans l’état 1 (Q=1) ;
• l’entrée R (Reset) est utilisée pour mettre la bascule dans l’état 0 (Q=0) ;
• la sortie 𝑄 donne l’état de la bascule (0 ou 1) ;
• la sortie 𝑄̅ donne le complément logique de la sortie 𝑄.

4.5.3.2 Les deux états stables de bascule SR


Pour comprendre le fonctionnement de la bascule SR, nous supposons tout d’abord que les entrées S
et R ne sont pas actives (valeur = 0).

Si la bascule se trouve dans l’état initial 0 (𝑄=0). Le signal de sortie 𝑄 est connecté à la deuxième
entrée de la porte NOR supérieure. Les 2 entrées de la porte supérieure sont donc à 0. Il en résulte
une valeur de sortie 𝑄̅ égale à 1 (vu que 0 + 0 = 1). Le signal 𝑄̅ est quant à lui connecté à la porte
NOR inférieure, dont les entrées valent donc 0 et 1. Il en résulte une valeur de sortie 𝑄 qui est égale à
0 (vu que 0 + 1 = 0). Le circuit est donc dans un état consistant et stable. C’est la situation décrite
par le schéma de gauche : 𝑄 = 0.

Si nous effectuons le même raisonnement en supposant que la bascule est dans l’état initial Q=1,
nous obtenons également un état consistant et stable. C’est la situation décrite par le schéma de
droite. C’est le deuxième état stable de la bascule SR : 𝑄 = 1.

Nous aboutissons donc à une constatation étonnante : pour des valeurs d’entrée identiques (S=0 et
R=0), la bascule SR peut présenter deux valeurs de sortie différentes (soit 0, soit 1) ! Un tel
comportement est impossible à obtenir avec un circuit combinatoire. Il s’explique par la présence des
boucles dans le circuit.

© HELMo Campus Guillemins Page 4.21


Les circuits logiques Architecture des ordinateurs - Théorie

4.5.3.3 Transition d’un état à l’autre


Set
Que se passe-t-il si, partant de l’état 0, nous activons le signal d’entrée S (S=1) ?

La sortie 𝑄̅ de la porte NOR supérieure passe dans l’état 0 (0 + 1 = 0). Les deux entrées de la porte
inférieure ont maintenant la valeur 0, de sorte que la sortie 𝑄 passe dans l’état 1 (0 + 0 = 1). Les
deux entrées de la porte supérieure ont finalement la valeur 1, ce qui ne modifie pas la valeur de
sortie de 𝑄̅ qui reste à 0 (1 + 1 = 0). La bascule est à présent dans l’état 1.

Plus intéressant encore, la situation reste inchangée lorsque nous désactivons le signal d’entrée S
(S=0). Les deux entrées de la porte supérieure valent alors 0 et 1, la sortie 𝑄̅ reste à 0 (0 + 1 = 0).

Si la bascule est déjà dans l’état 1, appliquer un signal d’entrée S=1 ne modifie rien : 𝑄̅ = 1 + 1 = 0.

Reset
Le même raisonnement montre qu’en appliquant un signal d’entrée R=1 à la bascule, elle passe dans
l’état 0 quel que soit son état de départ.

En conclusion, activer l’entrée S (Set) fait passer la bascule dans l’état 1. Activer l’entrée R (Reset) fait
passer la bascule dans l’état 0.

4.5.3.4 Instabilité de la bascule SR


Que se passe-t-il à présent si les deux entrées S et R sont mises simultanément à 1 ?

La bascule SR présente alors un problème d’instabilité. En effet, tant que les deux entrées valent 1,
les deux sorties valent 0, ce qui n’est déjà pas très cohérent avec notre hypothèse que les sorties 𝑄
et 𝑄̅ sont complémentaires l’une de l’autre.

Mais la véritable question est : quel sera l’état final de la bascule lorsque les sorties repassent à
zéro ? Si une entrée reste à 1 plus longtemps que l’autre, c’est elle qui gagne. Si les deux entrées
repassent à 0 en même temps, le résultat est imprévisible.

4.5.4 Bascule SR synchrone


4.5.4.1 Introduction
Le schéma logique présenté à la section 4.5.3.1 ci-dessus est en fait celui d’un verrou, car il s’agit d’un
circuit asynchrone. Les valeurs de sortie sont évaluées dès l’instant où les signaux d’entrée sont
appliqués.

Il peut être intéressant de contrôler à quel moment précis l’état du circuit doit être mis à jour. Pour
cela, nous allons rendre le circuit synchrone en utilisant un signal d’horloge.

Nous avons vu que si les signaux d’entrée S et R sont tous les deux à zéro, la bascule reste dans son
état stable courant. L’état de la bascule ne peut se modifier que si soit l’entrée S, soit l’entrée R passe

Page 4.22 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Les circuits logiques

à 1. Comment pouvons-nous contrôler à quel moment un signal d’entrée actif (=1) est autorisé à
pénétrer dans le circuit ?

Nous avons expliqué à la section 4.4.4, qu’il existe 4 possibilités pour se synchroniser sur un signal
d’horloge : niveau haut, niveau bas, transition montante, transition descendante. Explorons-les.

4.5.4.2 Synchronisation sur un niveau de l’horloge


Pour synchroniser l’acceptation d’un signal d’entrée E sur le niveau haut de l’horloge, nous pouvons
utiliser une simple porte ET à laquelle nous connectons le signal d’entrée à synchroniser et le signal
d’horloge. Si le signal d’horloge vaut 0, la valeur de sortie de la porte ET vaut 0, quelle que soit la
valeur du signal d’entrée E (E.0 = 0). Si le signal d’horloge vaut 1, la valeur de sortie de la porte ET est
égale à celle de E (E.1 = E).

Pour synchroniser l’entrée E sur le niveau bas de l’horloge, il suffit d’inverser la valeur du signal
d’horloge avec une porte NON (inverseur).

E E
S S

Figure 4-18 - Synchronisation sur les niveaux haut et bas d'une horloge

Le schéma ci-dessous présente la version synchrone sur niveau haut de la bascule SR. Comme nous
venons de l’expliquer, deux portes ET contrôle l’entrée des signaux S et R dans le circuit. Celle-ci est
autorisée uniquement lorsque le signal d’horloge vaut 1.

S
Q
Clock S Q
Clk
Q R Q
R

Figure 4-19 - Bascule SR synchrone sur niveau haut

Nous expliquons dans la section suivante comment réaliser une véritable bascule au sens strict du
terme, c’est-à-dire un circuit synchrone dont l’état change lors d’une transition du signal d’horloge.

4.5.4.3 Synchronisation sur une transition de l’horloge


Accepter la valeur d’un signal d’entrée à l’occasion d’une transition montante ou descendante du
signal d’horloge nécessite un peu plus de réflexion.

Nous pouvons conserver l’idée d’utiliser une porte ET pour contrôler le passage du signal d’entrée,
mais nous devons surtout concevoir un circuit capable de générer un « signal d’autorisation » qui
vaudra 1 uniquement pendant le court instant qui correspond à la transition du signal d’horloge de 0
vers 1 (ou de 1 vers 0).

© HELMo Campus Guillemins Page 4.23


Les circuits logiques Architecture des ordinateurs - Théorie

Un tel circuit porte le nom de générateur d’impulsions.

Il est constitué d’une porte ET aux entrées de laquelle on connecte le signal d’horloge et sa valeur
inversée. Mathématiquement parlant, la sortie de la porte ET devrait toujours valoir 0, puisqu’elle
reçoit en entrée deux valeurs inverses l’une de l’autre (𝑎. 𝑎 = 0). En pratique ce n’est pas le cas, car
l’inverseur (comme toute autre porte logique) prend un certain temps pour changer d’état.

Clock
b
c
a AND b
a

Temps

Figure 4-20 - Générateur d'impulsions sur transitions montantes

Lorsque le signal d’horloge (a) passe dans l’inverseur, le signal d’horloge inversé (b) est légèrement
en retard sur le signal initial à cause du délai de propagation induit par la porte NOT.

Si on réalise un ET logique entre les signaux (a) et (b), on obtient donc une courte impulsion (a ET b)
dont la durée est égale au délai de propagation dans la porte NOT. Cette impulsion est à son tour
légèrement décalée à cause du délai induit par la porte ET, pour donner l’impulsion finale (c).

Au final, le circuit de la Figure 4-19 génère un train de brèves impulsions déclenchées par chaque
transition montante du signal d’horloge.

En suivant le même principe, nous pouvons construire un générateur d’impulsions déclenchées par
les transitions descendantes de l’horloge en remplaçant la porte ET par une porte NOR.

Le schéma ci-dessous présente la version synchrone sur transition montante de la bascule SR. Les
deux portes ET et le générateur d’impulsion contrôle l’entrée des signaux S et R dans le circuit.

S
Q
Clock S Q
Clk
Q
R
R Q

Figure 4-21 - Bascule SR synchrone sur transition montante

Page 4.24 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Les circuits logiques

4.5.5 Bascule D
La bascule D (Delay ou Data) permet d’éviter le problème d’instabilité que la bascule SR présente
lorsque les 2 signaux d’entrée valent simultanément 1. Pour cela, on ne garde qu’un seul signal
d’entrée, appelé D. Ce signal alimente l’entrée supérieure de la bascule et son complément alimente
l’entrée inférieure. En procédant de la sorte, il devient impossible d’avoir 1 simultanément sur les
deux entrées de la bascule.

D
Q
Clock D Q

Q
Clk

Figure 4-22 - Bascule D synchrone sur niveau haut

Lorsque D vaut 1, on est dans la situation S=1/R=0 d’une bascule SR, la bascule passe dans l’état Q=1.
Lorsque D vaut 0, on est dans la situation S=0/R=1 d’une bascule SR, la bascule passe dans l’état Q=0.

Remarque : le schéma bloc à droite de la Figure 4-22 ne mentionne pas la sortie 𝑄. Cette sortie
complémentée n’est pas toujours disponible.

Tout comme nous l’avons déjà fait avec la bascule SR, nous pouvons créer une bascule D
synchronisée sur une transition du signal d’horloge en insérant le générateur d’impulsions adéquat
dans le circuit. Le schéma ci-dessous illustre le cas d’une synchronisation sur transition descendante
(le générateur d’impulsions utilise une porte NOR).

D
Clock Q
D Q

Q Clk

Figure 4-23 - Bascule D synchrone sur transition descendante

Dans la perspective qui est la nôtre, de chercher à construire un ordinateur, l’utilité principale d’une
bascule D est qu’elle permet de mémoriser la valeur appliquée à son entrée. Cette valeur mémorisée
est disponible en permanence à la sortie du circuit.

Une bascule D constitue donc une mémoire élémentaire de 1 bit !

© HELMo Campus Guillemins Page 4.25


Les circuits logiques Architecture des ordinateurs - Théorie

4.5.6 Registres de n bits


Nous avons vu dans la section précédente qu’une bascule D permet de mémoriser une information
de 1 bit. En pratique, nous souhaitons pouvoir mémoriser des données de plus grande taille (octet,
mots mémoires…)

Pour réaliser un registre mémoire de n bits, il nous suffit de connecter en parallèle n bascules D,
comme le montre le schéma suivant :

D3 D2 D1 D0

Write
D Q D Q D Q D Q
Clk
Clk Clk Clk Clk

S3 S2 S1 S0

Figure 4-24 - Registre de 4 bits

La donnée à mémoriser est appliquée aux entrées de données (Di) du registre.

L’écriture dans le registre nécessite deux choses :

1. Activer l’entrée Write du circuit à 1 pour indiquer notre intention de modifier le registre.
2. L’écriture proprement dite s’effectue lors de la transition montante suivante du signal
d’horloge (entrée Clock).

Une fois qu’une valeur est stockée dans le registre, elle reste disponible en permanence sur les lignes
de sortie (Si) jusqu’à la modification suivante du registre.

Le schéma présenté ci-dessus est extensible à une taille de registre quelconque.

4.5.7 Mémoires
Un registre permet de stocker une seule donnée d’une taille déterminée : 4, 8, 16, 32 ou 64 bits par
exemple.

Pour stocker davantage de données, nous pouvons bien sûr utiliser autant de registres que
nécessaire. Il est néanmoins indispensable d’ajouter une logique de contrôle d’accès à cette
collection de registres, de manière à pouvoir sélectionner correctement :

• le registre dans lequel la donnée d’entrée est écrite (accès en écriture) ; ou


• le registre dont le contenu est rendu disponible à la sortie de la mémoire (accès en lecture) .

L’accès à un mot mémoire spécifique est basé sur une adresse, c’est-à-dire un nombre binaire qui
indique quel est le registre concerné. Avec une adresse de k bits, on peut adresser 2k mots mémoire
différents. C’est pour cette raison que le nombre de mots dans un circuit mémoire est toujours égal à
une puissance de 2.

Page 4.26 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Les circuits logiques

Lors d’un accès en écriture (write), l’adresse de k bits doit permettre de sélectionner le registre dans
lequel écrire parmi les 2k mots mémoires. Nous sommes donc en présence d’un processus de
sélection « k vers 2k ». Un circuit décodeur ou démultiplexeur à k lignes de commande permet de
réaliser ce type d’opérations.

Lors d’un accès en lecture (read), l’adresse de k bits doit permettre de sélectionner celui des 2k mots
mémoires qui sera envoyé vers la sortie de la mémoire. Nous sommes donc en présence d’un
processus de sélection « 2k vers 1 ». Un circuit multiplexeur à k lignes de commande permet de
réaliser ce type d’opération.

Le schéma bloc ci-dessous illustre ce principe pour une mémoire de 4 mots dont les adresses ont une
taille de 2 bits.

Donnée
Adresse Write écrite

A0 E
A1 Demux « 2 vers 4 »
S3 S2 S1 S0

W D W D W D W D
R3 R2 R1... R0
S S S S

D3 D2 D1 D0
A0 Mux « 4 vers 1 »
A1 S
Read

Donnée lue

Figure 4-25 - Schéma bloc d'une mémoire de 4 mots

Le diagramme logique de la

Figure 4-26 présente une version détaillée possible du schéma bloc précédent pour une mémoire
contenant 4 mots de 4 bits chacun.

Bien que ce diagramme puisse paraître complexe à première vue, il n’en est rien, car le circuit est en
fait très régulier. Il peut être facilement étendu à une mémoire contenant plus de mots (répétition
des tranches horizontales) ou des mots plus longs (répétition des tranches verticales).

Chaque tranche horizontale du circuit correspond à un mot mémoire de 4 bits et adopte la même
structure que celle du registre de 4 bits présenté à la Figure 4-24.

Chaque ligne de donnée d’entrée Ei (E0 à E3) est câblée verticalement et est connectée à l’entrée D de
toutes les bascules stockant le bit i dans les différents mots mémoire.

La sélection d’un mot mémoire particulier est réalisée en décodant l’adresse. Dans notre exemple,
l’adresse est codée sur 2 bits ce qui permet d’adresser 4 mots mémoire distincts. Le décodage
nécessite par conséquent 4 portes ET à 2 entrées. Il s’agit d’un décodeur « 2 vers 4 ». Pour une

© HELMo Campus Guillemins Page 4.27


Les circuits logiques Architecture des ordinateurs - Théorie

adresse donnée, une seule porte ET sera activée et elle activera la ligne de sélection horizontale
correspondant au mot mémoire choisi.

E3
E2
E1
E0
Donnée
écrite
Contrôle D Q D Q D Q D Q
d’écriture
Mot 0
Clk Clk Clk Clk

00
Ligne de
sélection D Q D Q D Q D Q
mot 0
Mot 1
Clk Clk Clk Clk

01
Ligne de
A1 sélection D Q D Q D Q D Q
mot 1
A0 Mot 2
Clk Clk Clk Clk
Adresse

10
Ligne de
sélection D Q D Q D Q D Q
mot 2
Mot 3
Clk Clk Clk Clk

11
Ligne de
sélection
Décodage adresse mot 3
Sélection mot
Write de sortie
Read S3
S2
Contrôle de S1
la sortie
S0
Donnée
lue

Figure 4-26 - Schéma logique d’une mémoire de 4 x 4 bits

Une opération d’écriture se déroule de la façon suivante.

1. La donnée à écrire en mémoire est indiquée sur les entrées E0 à E3 (« Donnée écrite »).
2. L’adresse x du mot mémoire concerné est indiquée sur les entrées A0 à A1 (« Adresse »), ce
qui active la « Ligne de sélection mot x » de ce mot mémoire.
3. Lorsque le signal d’écriture « Write » est activé, une seule porte ET de « contrôle d’écriture »
est activée : celle qui correspond à la ligne de sélection du mot mémoire choisi.
4. La donnée d’entrée est écrite dans le mot mémoire sélectionné.

En ce qui concerne la lecture d’un mot mémoire, le principe est le suivant.

1. L’adresse x du mot mémoire demandé est indiquée sur les entrées A0 à A1, ce qui active la
« Ligne de sélection mot x » de ce mot mémoire.
2. La sortie de chaque bascule D est connectée à une porte ET (« Sélection mot de sortie ») dont
la deuxième entrée est raccordée à la ligne de sélection du mot mémoire dont cette bascule
fait partie.

Page 4.28 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Les circuits logiques

3. Cela signifie donc qu’au sein d’une même tranche verticale (bit i d’un mot mémoire), il ne
peut y avoir à un instant donné qu’une seule bascule dont le signal est envoyé vers la porte
OU de sortie : celle qui correspond au mot mémoire sélectionné.
4. La sortie de chaque porte OU à 4 entrées est donc égale au bit correspondant du mot
mémoire sélectionné.
Remarque : le lecteur attentif réalisera que la combinaison du décodeur d’adresse avec une
tranche verticale composée de 4 portes ET et une porte OU n’est en fait rien d’autre qu’un
multiplexeur « 4 vers 1 »
5. Les portes ET dans la partie inférieure du diagramme (« Contrôle de la sortie ») permettent
de garantir que le contenu d’un mot mémoire n’est disponible sur les portes de sortie S0 à S3
(« Donnée lue ») du circuit mémoire que lorsqu’une opération de lecture (« Read ») est
demandée.

En théorie, il est possible de généraliser le diagramme logique présenté ci-dessus pour réaliser un
circuit mémoire comportant un grand nombre de mots de taille quelconque.

En pratique, il existe des contraintes physiques qui rendent la chose impossible. Ainsi, si la taille d’un
mot mémoire augmente, le diagramme se répète horizontalement : on ajoute autant de tranches
verticales qu’il y a de bits dans le mot mémoire. Les problèmes qui surviennent sont :

• le délai de propagation du signal sur les lignes horizontales augmente, ce qui ralentit le
circuit (= le temps d’écriture ou de lecture augmente) ;
• l’atténuation progressive du signal diminue la fiabilité du circuit ou nécessite une
régénération du signal (consommation + délai).

Si le nombre de mots mémoire augmente, on a bien sûr les mêmes problèmes de délai et
d’atténuation, mais cette fois-ci sur les lignes verticales. On a également les problèmes additionnels
suivants :

• le décodage de l’adresse nécessite des portes ET avec autant d’entrées qu’il y a de bits
d’adresse ;
• les portes OU de sortie doivent avoir autant d’entrées qu’il y a de mots mémoire !!!

Pour toutes ses raisons, la capacité d’un seul circuit mémoire sera généralement limitée afin de
pousser au maximum son optimisation. On construira des mémoires de grande capacité en
assemblant intelligemment des circuits de capacité plus faible.

L’idée générale est illustrée par le schéma de principe de la Figure 4-27 ci-dessous. Si on dispose de
circuits de 4 mots de 4 bits, on peut construire une mémoire de 16 mots de 8 bits en assemblant 8 de
ces circuits.

© HELMo Campus Guillemins Page 4.29


Les circuits logiques Architecture des ordinateurs - Théorie

Mémoire 16x8

4x4 4x4

4x4 4x4

4x4 4x4

4x4 4x4

Figure 4-27 - Exemple de mémoire 16x8

Pour adresser 16 mots mémoire, il faut une adresse de 4 bits (24=16). Les 2 bits de poids fort de
l’adresse servent à sélectionner une des 4 rangées de circuits. Les deux bits de poids faible de
l’adresse permettent de sélectionner 1 des 4 mots mémoire dans les circuits de la rangée
sélectionnée.

Page 4.30 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie L’unité centrale de traitement (CPU)

5 L’unité centrale de
5 traitement (CPU)

5.1 Introduction
Dans les chapitres précédents, nous avons expliqué comment il est possible de représenter différents
types d’informations en utilisant le système binaire. Nous avons également montré comment nous
pouvons construire divers circuits logiques et notamment les principaux composants de base d’un
ordinateur : unité arithmétique et logique (ALU), registre, mémoire.

Dans ce chapitre, nous allons expliquer comment utiliser ces connaissances pour construire une unité
centrale de traitement (CPU), c’est-à-dire un circuit électronique capable d’exécuter les instructions
d’un programme stocké en mémoire.

Il va de soi qu’un CPU réel est un circuit extrêmement complexe, qui est optimisé pour obtenir une
performance maximale. Nous nous contenterons de construire ici un CPU fictif très simplifié.

Notre processeur idéalisé est basé sur une architecture de type RISC inspirée de celle du processeur
MIPS. Nous avons choisi cette architecture pour sa relative simplicité. Elle nous permet d’illustrer la
mise en œuvre d’un CPU sans devoir entrer dans des considérations trop avancées.

5.2 Code machine et langage d’assemblage


5.2.1 Le code machine
Nous avons expliqué au chapitre 2, que la microarchitecture d’un ordinateur, c’est-à-dire
l’architecture du CPU, détermine les instructions qui peuvent être exécutées directement par le
processeur.

Chaque instruction est représentée en mémoire par un code binaire, appelé code machine, qui
spécifie le type d’instruction à exécuter ainsi que ses arguments éventuels.

La liste complète des instructions comprises par un processeur ainsi que la spécification précise de
leur représentation interne (code machine) constituent l’architecture du jeu d’instructions ou ISA
(Instruction Set Architecture). C’est la bible de référence indispensable pour tout processeur.

Dans l’architecture MIPS, dont nous nous inspirons, les instructions sont représentées par un code
machine dont la taille est identique pour toutes les instructions, à savoir 32 bits, soit 4 octets.

© HELMo Campus Guillemins Page 5.1


L’unité centrale de traitement (CPU) Architecture des ordinateurs - Théorie

Chaque instruction est alignée sur un mot mémoire de 32 bits. Par conséquent, l’adresse de début
d’une instruction en mémoire sera toujours un multiple de 4.

Suivant la nature de l’instruction à exécuter, le code machine MIPS utilise un des 3 formats suivants :

31 26 25 21 20 16 15 11 10 6 5 0
R OPCODE RS RT RD SHAMT FUNCT
I OPCODE RS RT CONSTANT/ADDRESS
J OPCODE ADDRESS
Figure 5-1 - Formats des instructions (code machine)

Les éléments constitutifs du code machine MIPS sont les suivants :

• OPCODE (Operation Code) – Il est présent dans toutes les instructions. L’opcode indique le
type d’instruction à exécuter (ex. opération arithmétique). Il permet également de
déterminer le format utilisé (R, I, J).

Champs du format ‘R’ :

• RS – Numéro du registre source contenant le premier opérande de l’instruction.


• RT – Numéro du registre source contenant le deuxième opérande de l’instruction.
• RD – Numéro du registre de destination où stocker le résultat de l’opération.
• SHAMT (Shift Amount) – Quantité de décalage utilisée par les instructions de décalage.
• FUNCT (Function) – Code de fonction qui spécifie une variante du type d’instruction de base
donné par le opcode (ex. addition, soustraction…).

Champs du format ‘I’ :

• RS – Numéro du registre contenant le premier opérande de l’instruction.


• RT – Numéro du registre où stocker le résultat de l’opération ou du registre contenant une
donnée à stocker en mémoire.
• CONSTANT – Une constante sur 16 bits spécifiée dans l’instruction (valeur maximum = ±215 =
±32768).
• ADDRESS – Une adresse mémoire sur 16 bits.

Champs du format ‘J’ :

• ADDRESS – Une adresse mémoire sur 26 bits.

En simplifiant un peu les choses, nous pouvons dire que les différents formats sont utilisés dans les
cas suivants :

• Format R (Register) – Instructions arithmétiques et logiques. Les opérandes sont disponibles


dans les registres du processeur, le résultat est lui aussi stocké dans un registre.
• Format I (Immediate)
o Instructions arithmétiques et logiques pour lesquelles le premier opérande est
stocké dans un registre et le second opérande est une constante sur 16 bits.
o Instructions de transfert de données entre registre et mémoire.

Page 5.2 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie L’unité centrale de traitement (CPU)

o Instructions de branchement conditionnel de programme vers une adresse.


• Format J (Jump) – Instructions de saut de programme vers une adresse.

5.2.2 Les registres du CPU


Notre processeur comporte un certain nombre de registres, c’est-à-dire des mémoires très rapides
qui permettent de stocker les données utilisées par le CPU. Chaque registre a une taille de 32 bits.

Dans les instructions MIPS, un registre est identifié par un numéro sur 5 bits : il y a donc au maximum
32 registres généraux adressables et utilisables par le programmeur

Chaque registre est destiné à un usage spécifique qui est fonction de son numéro. Chaque registre
porte également un nom qui reflète cet usage :

NUM NOM USAGE


0 $zero Valeur constante 0
1 $at Temporaire réservé à l’assembleur
2-3 $v0-$v1 Valeurs de résultat (évaluation de fonctions ou d’expressions)
4-7 $a0-$a3 Arguments (appel de sous-programme)
8-15 $t0-$t7 Temporaires
16-23 $s0-$s7 Temporaires sauvegardés lors d’un appel de sous-programme
24-25 $t8-$t9 Temporaires
26-27 $k0-$k1 Réservé pour le noyau (Kernel)
28 $gp Pointeur global (Global Pointer)
29 $sp Pointeur de pile (Stack Pointer) [Gestion des sous-programmes]
30 $fp Pointeur de fenêtre (Frame Pointer) [Gestion des sous-programmes]
31 $ra Adresse de retour (Return Address) [Gestion des sous-programmes]
Figure 5-2 - Les 32 registres du processeur MIPS

Outre ces 32 registres qui peuvent être référencés dans les instructions et dont le contenu peut être
modifié par le programme, notre CPU possède également quelques registres indispensables à son
fonctionnement interne, notamment :

• Le compteur ordinal ou pointeur d’instruction, PC (Program Counter), qui indique l’adresse en


mémoire de l’instruction courante.
• Le registre d’instruction, IR (Instruction Register), qui contient le code machine de
l’instruction courante.

Ces deux registres ne sont pas accessibles au programmeur.

5.2.3 Le langage d’assemblage


Il n’est vraiment pas commode de programmer directement en langage machine. On préférera plutôt
utiliser un langage d’assemblage. Il s’agit d’un langage de bas niveau qui permet de représenter de
manière symbolique les différentes instructions offertes par le processeur.

Ainsi, l’instruction-machine qui réalise l’addition signée de deux registres est représentée
symboliquement dans le langage d’assemblage MIPS par :

add <reg_dest>, <reg_op1>, <reg_op2>

© HELMo Campus Guillemins Page 5.3


L’unité centrale de traitement (CPU) Architecture des ordinateurs - Théorie

Ainsi, si on souhaite additionner le contenu des registres $s0 et $s1 et placer le résultat dans le
registre $t0, on écrira simplement :

add $t0, $s0, $s1 # $t0 = $s0 + $s1

Un programme spécial, appelé assembleur, se charge de convertir cette instruction symbolique vers
le code machine correspondant, à savoir :

R OPCODE RS RT RD SHAMT FUNCT


R 0 16 17 8 0 32
R 000000 10000 10001 01000 00000 100000

Catégorie Instruction Exemple Signification Commentaire

add add $s1, $s2, $s3 $s1 = $s2 + $s3 Addition : opérandes dans 3 registres
Arith- subtract sub $s1, $s2, $s3 $s1 = $s2 - $s3 Soustraction : opérandes dans 3 registres
métique
add immediate addi $s1, $s2, 20 $s1 = $s2 + 20 Utilisée pour ajouter une constante
load word lw $s1, 20($s2) $s1 = Memory[$s2 + 20] Mot : mémoire vers registre

store word sw $s1, 20($s2) Memory[$s2 + 20] = $s1 Mot : registre vers mémoire
load half lh $s1, 20($s2) $s1 = Memory[$s2 + 20] Demi-mot : mémoire vers registre
load half unsigned lhu $s1, 20($s2) $s1 = Memory[$s2 + 20] Demi-mot non signé : mém. vers registre
Transfert store half lh $s1, 20($s2) Memory[$s2 + 20] = $s1 Demi-mot : registre vers mémoire
de données
load byte lb $s1, 20($s2) $s1 = Memory[$s2 + 20] Octet : mémoire vers registre

load byte unsigned lbu $s1, 20($s2) $s1 = Memory[$s2 + 20] Octet non signé : mémoire vers registre
store byte sb $s1, 20($s2) Memory[$s2 + 20] = $s1 Octet : registre vers mémoire
load upper immed. lui $s1, 20 $s1 = 20 * 216 Constante dans 16 bits de poids forts
and and $s1, $s2, $s3 $s1 = $s2 & $s3 ET bit-à-bit : opérandes dans 3 registres
or or $s1, $s2, $s3 $s1 = $s2 | $s3 OU bit-à-bit : opérandes dans 3 registres
nor nor $s1, $s2, $s3 $s1 = ~($s2 | $s3) NOR bit-à-bit : opérandes dans 3 registres
Logique and immediate andi $s1, $s2, 20 $s1 = $s2 & 20 ET bit-à-bit : registre avec constante

or immediate ori $s1, $s2, 20 $s1 = $s2 | 20 OU bit-à-bit : registre avec constante
shift left logical sll $s1, $s2, 10 $s1 = $s2 << 10 Décalage à gauche valeur de la constante
shif right logical srl $s1, $s2, 10 $s1 = $s2 >> 10 Décalage à droite valeur de la constante
branch on equal beq $s1, $s2, 25 if ($s1 == $s2) go to Test d’égalité; branchement relatif à PC
PC + 4 + 100
branch on not equal bne $s1, $s2, 25 if ($s1 != $s2) go to Test d’inégalité; branchement relatif à PC
PC + 4 + 100
set on less than slt $s1, $s2, $s3 if ($s2 < $s3) $s1 = 1; Comparaison « inférieur à »
else $s1 = 0
Branchement
conditionnel set on less than sltu $s1, $s2, $s3 if ($s2 < $s3) $s1 = 1; Comparaison « inférieur à » non signée
unsigned else $s1 = 0

set on less than slti $s1, $s2, 20 if ($s2 < 20) $s1 = 1; Comparaison « inférieur à » constante
immediate else $s1 = 0

set on less than sltiu $s1, $s2, 20 if ($s2 < 20) $s1 = 1; Comparaison « inférieur à » constante
immediate unsigned else $s1 = 0 non signée
jump j 2500 go to 10000 Saut vers adresse de destination
Saut incon- jump register jr $ra go to $ra Saut vers adresse dans registre
ditionnel
jump and link jal 2500 $ra=PC+4; go to 10000 Appel d’un sous-programme

Figure 5-3 - Résumé du langage d'assemblage MIPS

Page 5.4 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie L’unité centrale de traitement (CPU)

Pour une référence plus complète, on peut par exemple consulter la page Wikipedia suivante :
http://en.wikipedia.org/wiki/MIPS_instruction_set#Integer

Les langages de haut niveau permettent d’exprimer des expressions de calcul complexes avec une
seule instruction. Par exemple : r = m + n + o - p. Ce n’est pas le cas pour un langage d’assemblage
qui est composé d’instructions de base assez rudimentaires.

Pour calculer l’expression mathématique précédente, il faut la décomposer en une suite


d’instructions plus simples. Supposons les valeurs des variables m, n, o et p se trouvent dans les
registres $t1, $t2, $t3 et $t4, et que l’on veut placer le résultat r dans le registre $t0. Le programme
en langage d’assemblage est le suivant :

add $t0, $t1, $t2 # $t0 = $t1 + $t2 -> r = m + n


add $t0, $t0, $t3 # $t0 = $t0 + $t3 -> r = m + n + o
sub $t0, $t0, $t4 # $t0 = $t0 - $t4 -> r = m + n + o - p

Un langage d’assemblage propose également des fonctionnalités additionnelles telles que :

• Pseudo-instructions (implémentées par une ou plusieurs instructions de base)


Par exemple, l’instruction move permet de transférer le contenu d’un registre dans un autre
registre. Elle n’existe pas en tant que telle dans le jeu d’instruction MIPS. Simplement,
l’assembleur remplace l’instruction move $t2, $t1 par add $t2, $zero, $t1 ce qui
conduit au même résultat. En effet, $t2=$t1 est équivalent à $t2=0+$t1.
• Labels – Identifient une adresse en mémoire
Typiquement, un label est utilisé pour indiquer l’adresse d’une instruction d’un programme
vers laquelle un branchement pourra avoir lieu (voir exemple à la section 5.2.6).
• Commentaires – Annotations textuelles du programme. Ils débutent par le caractère ‘#’.
• Macros, procédures, directives d’assemblage, etc.

5.2.4 Les modes d’adressage


Nous terminons cette partie consacrée au langage d’assemblage par une présentation des différents
modes d’adressage.

Un mode d’adressage est une méthode utilisée pour calculer la valeur d’une adresse en mémoire à
partir des opérandes d’une instruction (adresse, constante, numéro de registre) et/ou du contenu
d’un registre spécial tel que le compteur ordinal (PC).

On peut avoir besoin de calculer une adresse pour déterminer :

• où se trouve la prochaine instruction à exécuter (branchement),


• l’emplacement d’une donnée.

© HELMo Campus Guillemins Page 5.5


L’unité centrale de traitement (CPU) Architecture des ordinateurs - Théorie

Dans le cas d’une instruction de branchement, on distingue les principaux modes d’adressage
suivants :

• Adressage absolu – L’adresse effective de l’instruction suivante est spécifiée dans


l’instruction. [Format ‘J’]

j 400 # jump 400 -> saut vers l’adresse 1600 (400*4)

• Adressage relatif – L’adresse effective de l’instruction suivante est obtenue à partir de


l’adresse contenue dans le compteur ordinal (PC) en lui ajoutant/retranchant une certaine
quantité spécifiée dans l’instruction. [Format ‘I’]

beq $s1,$s2,25 # if ($s1==$s2) branch to PC+4 + 100 (25*4)

• Adressage indirect – L’instruction indique dans quel registre se trouve l’adresse effective de
l’instruction suivante. [Format ‘R’]

jr $ra # saut vers l’adresse contenue dans $ra

Dans le cas de l’accès à une donnée, on distingue les principaux modes d’adressage suivants :

• Adressage immédiat – La donnée est présente directement dans l’instruction. Il n’y a donc
pas d’adressage à proprement parler. [Format ‘I’]

addi $s1,$s2,150 # $s1 = $s2 + 150

• Adressage implicite – L’opération utilise un registre qui est prédéfini par le processeur.

mult $s1,$s2 # {Hi,Lo} = $s1*$s2 [Hi et Lo = registres spéciaux MIPS]

• Adressage direct – L’instruction indique le registre qui la contient donnée ou l’adresse de la


donnée en mémoire.

add $s1,$s2,$s3 # $s1 = $s2+$s3

lw $s1, 1500 # $s1 = MEM[1500] [pseudo → lw $s1, 1500($zero)]

• Adressage indexé – L’adresse effective est obtenue en additionnant un certain décalage à


une adresse de base contenue dans un registre.

lw $s1, 100($s2) # $s1 = MEM[$s2+100]

• Adressage indirect – L’instruction indique le registre ou l’adresse en mémoire où se trouve


l’adresse de la donnée.

lw $s1, ($s2) # $s1 = MEM[$s2] [pseudo → lw $s1, 0($s2)]

lw $s1, [100] # $s1 = MEM[MEM[100]] [adressage non supporté par MIPS]

Page 5.6 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie L’unité centrale de traitement (CPU)

5.2.5 Particularités d’adressage du processeur MIPS


Le processeur MIPS présente quelques particularités au niveau de la manière dont fonctionnent les
différents modes d’adressage.

En effet, toutes les instructions ont une taille fixe de 32 bits, dont au moins 6 bits sont utilisés pour
l’opcode. Il reste donc au maximum 26 bits pour spécifier une adresse dans le format J et seulement
16 bits dans le format I. Or, une adresse complète nécessite 32 bits ! Comment faire pour s’en sortir ?

Nous avons indiqué à la section 5.2.1 qu’une instruction est toujours alignée sur un mot mémoire.
Par conséquent, son adresse est toujours un multiple de 4. Cela signifie que les deux derniers bits de
poids faible valent ‘0’. Il n’est donc pas utile de les préciser.

Ainsi, lorsqu’une instruction fait référence à l’adresse 400, elle désigne en réalité le mot mémoire
400, c’est-à-dire l’adresse 400*4=1600.

Dans le cas du jump (format J), l’adresse finale s’obtient en concaténant :

• les 4 bits de poids fort [31:28] du compteur ordinal (en réalité PC+4) ;
[voir remarque importante ci-dessous]
• les 26 bits d’adresse contenus dans l’instruction ;
• et 2 bits à 0.

L’instruction jump (j) utilise un mode d’adressage absolu, car l’adresse de l’instruction suivante est
précisée directement dans l’instruction. Ce type de branchement est illustré à la figure suivante.

Adresse Mot Instruction


0 0 instruction 1
4 1 instruction 2
8 2 instruction 3
… … …
100 25 add $t1, $s0, $s2
instruction courante → 104 26 j 400
Branchement inconditionnel
108 27 addi $t0, $t0, 1 et absolu vers l'instruction
… … … située au mot 400.
instruction suivante → 1600 400 add $t0, $zero, $zero
1604 401 …
… … …
Figure 5-4 - Branchement inconditionnel et absolu

Remarque importante : les 4 bits de poids fort du compteur ordinal étant utilisés sans modifications,
il faut obligatoirement que l’adresse finale à atteindre débute effectivement par ces 4 bits, ce qui
correspond à un bloc de 256MB en mémoire.

Le découpage en bloc de la mémoire est illustré à la figure suivante. Les registres ont une taille de 32
bits, ce qui limite la taille de la mémoire adressable à 4GB (=232 octets). Celle-ci est divisée en 16 (=24)
blocs de 256MB (=228 octets). Chaque bloc peut être identifié par un numéro de 4 bits. Il contient
226 = 64M mots mémoire de 4 octets.

© HELMo Campus Guillemins Page 5.7


L’unité centrale de traitement (CPU) Architecture des ordinateurs - Théorie

Préfixe bloc Adresse instruction 00


(4 bits) (26 bits) (2 bits)
0000 00000000000000000000000000 00
0000 00000000000000000000000001 00
Bloc 0
...
0000 11111111111111111111111111 00
0001 00000000000000000000000000 00
0001 00000000000000000000000001 00
Bloc 1
...
0001 11111111111111111111111111 00
... ... ... ...
1111 00000000000000000000000000 00
Bloc 1111 00000000000000000000000001 00
15 ...
1111 11111111111111111111111111 00
Figure 5-5 - Découpage de la mémoire en blocs de 64M mots mémoire

L’instruction jump (j) ne permet pas d’atteindre une instruction située en dehors du bloc courant !
Dès lors, pour pouvoir atteindre de cette manière toutes les instructions du programme, il faut que :

1. le programme ait une taille inférieure à 228 octets (28 = 32-4), soit 256MB, ou encore 64M
instructions puisque chaque instruction occupe 4 octets ; et que
2. le programme soit positionné en mémoire de manière à ne pas être à cheval sur deux blocs
de 256MB.

Si ce n’est pas le cas, il faut utiliser une autre méthode de branchement (adressage relatif ou
indirect).

Dans le cas d’une instruction de branchement (format I), la situation est encore plus critique que
pour une instruction jump, car on dispose de seulement 16 bits pour spécifier une adresse !

En pratique, on observe cependant qu’une instruction de branchement est généralement utilisée


dans le cadre d’une boucle, d’un switch ou d’une structure alternative if/else. Si un branchement
survient, l’exécution se poursuit le plus souvent par une instruction située dans un voisinage
relativement proche.

Aussi, plutôt que de spécifier une adresse absolue, le champ « adresse / constante » d’une
instruction de branchement indiquera un décalage par rapport à l’instruction courante (PC), ou plus
exactement par rapport à l’instruction suivante légitime (PC+4).

L’instruction branch (beq, bne, …) utilise un mode d’adressage relatif, car l’adresse de
l’instruction suivante est exprimée par rapport à celle de l’instruction courante.

Puisque nous disposons de 16 bits pour exprimer le décalage, le branchement peut s’effectuer dans
une zone de ±215 = ±32.768 mots (instructions) par rapport à l’instruction courante ce qui est
largement suffisant dans la grande majorité des cas. L’adresse effective de l’instruction suivante
s’obtient donc comme suit :

• (PC+4) + décalage, où
• Décalage = constante de l’instruction (sur 16 bits) avec extension de signe à 30 bits + 00.
(Voir section 3.4.3.3 pour un rappel sur l’extension de signe.)

Page 5.8 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie L’unité centrale de traitement (CPU)

Adresse Mot Instruction


0 0 instruction 1
4 1 instruction 2
8 2 instruction 3
… … …
100 25 addi $t0, $zero, 100
instruction suivante 104 26 addi $t1, $zero, 0
si branchement → 108 27 add $s0, $s0, $s1 Branchement conditionnel
… … … et relatif vers l'instruction 27
160 40 addi $t1, $t1, 1 si $t0 != $t1.
instruction courante → 164 41 bne $t0, $t1, -15
instruction suivante → 168 42 add $t0, $zero, $zero PC+4 = 168
sans branchement … … … → 168 + (-15*4) = 108
Figure 5-6 - Branchement conditionnel et relatif

S’il n’est pas possible d’atteindre l’adresse voulue par une de ces deux méthodes (jump, branch),
alors la seule solution consiste à charger l’adresse sur 32 bits dans un registre et à utiliser le mode
d’adressage indirect : jump register (jr).

Exercice : comment est-il possible charger une adresse/constante sur 32 bits dans un registre,
sachant que les instructions de format I acceptent uniquement des constantes sur 16 bits ?

5.2.6 Exemple d’un programme en langage d’assemblage


Pour terminer cette partie consacrée au langage d’assemblage, nous présentons un exemple de
programme un peu plus complexe, afin d’illustrer le passage d’un langage de haut niveau tel que le
langage C vers du code en langage d’assemblage.

(Exemple adapté de « Computer Organization and Design », David A. Patterson & John L. Hennessy,
Ed. Morgan Kaufmann, Section 2.9, page 108.)

void strcpy(char x[], char y[])


{
int i;
i = 0;
while ((x[i] = y[i]) != ‘\0’) { // On copie puis on teste le caractère
i = i + 1;
};
}

Nous supposons que les adresses de base des tableaux x[] et y[] se trouvent dans les registres $a0
et $a1.

Les registres temporaires $t0, $t1, $t2 et $t3 sont utilisés de la manière suivante :

• $t0 correspond à la variable i,


• $t1 contient l’adresse de l’élément courant dans la tableau y[] → adr(y[i]),
• $t2 contient le caractère courant à copier → y[i],
• $t3 contient l’adresse de l’élément courant dans la tableau x[] → adr(x[i]).

© HELMo Campus Guillemins Page 5.9


L’unité centrale de traitement (CPU) Architecture des ordinateurs - Théorie

Voici le programme en assembleur qui correspond au programme ci-dessus.

add $t0,$zero,$zero # $t0 = 0 + 0 | i = 0


L1: add $t1, $a1, $t0 # $t1 = $a1 + $t0 | t1 = adr(y[0])+i = adr(y[i])
lbu $t2, 0($t1) # $t2 = M[$t1+0] | t2 = y[i]
add $t3, $a0, $t0 # $t3 = $a0 + $t0 | t3 = adr(x[0])+i = adr(x[i])
sb $t2, 0($t3) # M[$t3+0] = $t2 | x[i] = t2
beq $t2, $zero, L2 # si ($t2 == 0) aller à L2
addi $t0, $t0, 1 # $t0 = $t0 + 1 | i = i + 1
j L1 # aller à L1
L2: # fin du strcpy

5.2.7 Exemple avancé : la suite de Fibonacci


La suite de Fibonacci est une suite de nombres dans laquelle chaque terme est obtenu en
additionnant les deux termes précédents. Classiquement, les 2 premiers termes sont 0 et 1. On
obtient donc la suite : 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144…

Cette suite peut être calculée au moyen du programme Java suivant :

final int N = 12; // Nombre de termes à calculer (N >= 2)

int t0 = N;
int t1 = 0;
System.out.println(t1);
t0 = t0 – 1;

int t2 = 1;
System.out.println(t2);
t0 = t0 – 1;

while (t0 > 0) {


t3 = t1 + t2;
System.out.println(t3);
t1 = t2;
t2 = t3;
t0 = t0 – 1;
}
exit(0);

Le programme en langage d’assemblage qui suit est une traduction assez directe du programme en
Java. Les différences principales sont :

• En Java, la boucle « while » exprime une condition de poursuite (t0 > 0). En assembleur
l’instruction « blez » exprime une condition d’arrêt : branchement si (t0 <= 0).

Page 5.10 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie L’unité centrale de traitement (CPU)

• L’instruction Java « System.out.println() » est remplacée par un appel au sous-


programme PRINT. La valeur à afficher est passée en argument via le registre $a0.
L’affichage proprement dit est réalisé au moyen d’un appel système « syscall ».

#
# fibonnacci() - Calcul des N premiers termes de la suite de Fibonnacci
# -> 0 1 1 2 3 5 8 13 21 34 55 89 144 ...
#
# Données constantes
.data
N: .word 12 # Nombre de termes à calculer
# Programme
.text
lw $t0, N # On initialise $t0 avec N (On suppose N >= 2)
add $t1, $zero, $zero # On initialise le premier terme
move $a0, $t1 # On charge la valeur entière à afficher dans $a0
jal PRINT # Appel du sous-programme d'impression -> print($a0)
addi $t0, $t0, -1 # On décrémente $t0

li $t2, 1 # On initialise le deuxième terme


move $a0, $t2 # On charge la valeur entière à afficher dans $a0
jal PRINT # Appel du sous-programme d'impression -> print($a0)
addi $t0, $t0, -1 # On décrémente $t0

LOOP: blez $t0, END # Si $t0 <= 0 , on a fini


add $t3, $t1, $t2 # On calcule le terme suivant ($t3 = $t1 + $t2)
move $a0, $t3 # On charge la valeur entière à afficher dans $a0
jal PRINT # Appel du sous-programme d'impression -> print($a0)
move $t1, $t2 # On décale les termes
move $t2, $t3
addi $t0, $t0, -1 # On décrémente $t0
j LOOP # On passe à l'itération suivante
END: li $v0, 10 # Appel système : 10 = exit
syscall # -> Fin du programme

#
# Sous-programme d'impression d'un terme de la suite
#
PRINT: li $v0, 1 # Appel système : 1 = impression d'un entier
syscall # -> Affichage du terme suivant (valeur dans $a0)
li $a0, 10 # Charge le code ASCII du retour à la ligne '\n'
li $v0, 11 # Appel système : 11 = impression d'un caractère
syscall # -> Affichage du retour à la ligne (ascii dans $a0)
jr $ra # Retour du sous-programme d’impression (return)

© HELMo Campus Guillemins Page 5.11


L’unité centrale de traitement (CPU) Architecture des ordinateurs - Théorie

5.3 Construire un chemin de données


(datapath)
5.3.1 Objectif
Entrons à présent dans le vif du sujet. Le contenu de cette section est largement basé sur celui de
« Computer Organization and Design », David A. Patterson & John L. Hennessy, Ed. Morgan
Kaufmann, Section 4.3 ».

Nous nous fixons comme objectif de construire un processeur capable d’exécuter un nombre limité
d’instructions.

• Instructions arithmétiques et logiques (cf. ALU de la section 4.3).


• Transferts de données avec la mémoire: load word (lw), store word (sw).
• Contrôle de séquence: branch on equal (beq).

5.3.2 Le cycle d’instruction


La tâche de notre processeur est très répétitive. Elle consiste à répéter en boucle la séquence
d’opérations suivante :

1. Aller chercher en mémoire l’instruction dont l’adresse est stockée dans le compteur ordinal
(PC), puis ajouter 4 à la valeur du compteur ordinal (= adresse de l’instruction suivante).
2. Décoder l’instruction pour déterminer l’opération à réaliser, ainsi que le type et
l’emplacement des opérandes.
3. Obtenir les valeurs des opérandes (contenu d’un registre, contenu d’un mot mémoire,
constante ou adresse spécifiée directement dans l’instruction).
4. Exécuter l’instruction.
5. Sauvegarder le résultat éventuel (registre, mémoire), modifier la valeur du compteur ordinal
dans le cas d’un branchement.
6. Répéter la séquence au point 1

Cette séquence porte le nom de cycle d’instruction (instruction cycle).

Construire un processeur consiste donc à assembler les composants qui permettent de mettre en
œuvre cette séquence d’opérations en tenant compte des différents types d’instructions.

Le circuit qui matérialise cette séquence, c’est-à-dire le cheminement des données à chaque étape
du cycle d’instruction, s’appelle un chemin de données (datapath).

Page 5.12 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie L’unité centrale de traitement (CPU)

5.3.3 Obtention des instructions


La première partie de notre chemin de données va servir à aller chercher les instructions en mémoire
et à mettre à jour le compteur ordinal (PC).

Pour simplifier notre tâche, nous supposons que la mémoire contenant les instructions du
programme est distincte de celle qui contient les données.

Les éléments utilisés sont donc :

Adresse
Add
P
Instruction somme
C
Mémoire
d’instructions

C’est-à-dire :

• La mémoire contenant les instructions du programme.


• Le registre PC (compteur ordinal) qui contient l’adresse de l’instruction à exécuter.
• Un additionneur sur 32 bits pour calculer l’adresse de l’instruction suivante.

Si on ne tient pas compte des instructions de branchement qui peuvent introduire une rupture de
séquence, le circuit suivant permet d’aller chercher les instructions en mémoire et d’incrémenter le
compteur ordinal.

Add
4

P Adresse
C (read)
Instruction

Mémoire
d’instructions

Figure 5-7 - Chemin de données pour le séquencement des instructions

5.3.4 Instructions de type R


Les instructions utilisant le format R opèrent exclusivement sur des registres. Les deux opérandes se
trouvent dans deux registres dont les numéros sont indiqués dans l’instruction. Le résultat est stocké
dans un registre dont le numéro est lui aussi indiqué dans l’instruction.

Exemple : add $t0, $s0, $s1 → $t0=$s0+$s1 → rs = $s0/16, rt=$s1/17, rd=$t0/8

Les éléments supplémentaires dont nous avons besoin sont :

• Une banque de 32 registres de 32 bits.


• Une unité arithmétique et logique (ALU) capable d’effectuer diverses opérations.

© HELMo Campus Guillemins Page 5.13


L’unité centrale de traitement (CPU) Architecture des ordinateurs - Théorie

/5 Read
register 1
Read /32
/5 Read data 1 ALUop
register 2
Registres zéro
/5
ALU
Write résultat
register Read /32
data 2
/32 Write
data

RegWrite

La banque de registres permet d’accéder en lecture à 2 registres dont les numéros (sur 5 bits) sont
indiqués en entrée : read register 1 et read register 2.

Les valeurs stockées dans les registres qui correspondent à ces numéros sont disponibles en
permanence sur les sorties read data 1 et read data 2 du circuit.

La banque de registres permet également d’écrire une donnée (write data) dans un troisième
registre dont le numéro (sur 5 bits) est spécifié en entrée (write register). La décision d’écrire ou pas
la donnée dans le registre est contrôlée par une ligne de contrôle (RegWrite).

L’ALU dispose de deux entrées sur 32 bits et fournit un résultat sur 32 bits. L’opération à réaliser est
déterminée par l’entrée de contrôle ALUop dont le nombre de bits dépend du nombre d’opérations
distinctes supportées par l’ALU. L’ALU fournit également un signal de sortie spécial « zéro » qui est
actif (= 1) lorsque le résultat est nul. Ce signal « zéro » servira plus tard dans le cadre de l’instruction
de branchement beq (branch if equal).

Le morceau du chemin de données correspondant aux instructions de type R est le suivant :

rs Read
register 1
Read ALUop
rt Read data 1
instruction register 2
zéro
Registres ALU
résultat
rd Write
register Read
data 2
value Write
data

RegWrite

Figure 5-8 - Chemin de données pour les instructions de type R

Les numéros des 3 registres sont extraits directement des champs de l’instruction : rs et rt indiquent
les numéros des registres contenant les 2 opérandes, rd celui du registre où stocker le résultat.

L’ALU reçoit en entrée les données stockées dans les 2 registres d’opérandes. Sa sortie résultat est
connectée à l’entrée write data de la banque de registres, ce qui permet de sauvegarder la valeur du
résultat du calcul dans le registre indiqué par le champ rd de l’instruction (write register).

Page 5.14 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie L’unité centrale de traitement (CPU)

5.3.5 Instructions de transfert avec la mémoire


Les instructions de transfert entre un registre et la mémoire sont des instructions de type I.

L’instruction load word (lw) permet de charger un mot mémoire dans un registre. Elle consiste à
réaliser l’opération suivante :

R[rt] = Mem[ R[rs]+SignExtImm ]

Où R[x] représente le registre numéro x et Mem[y] la cellule mémoire d’adresse y.

L’adresse mémoire effective est obtenue en additionnant :

• R[rs] : c’est-à-dire la valeur (adresse) contenue dans le registre spécifié par le champ « rs »
de l’instruction ; et
• SignExtImm (Sign Extend Immediate) : qui correspond à la constante signée sur 16 bits
spécifiée dans l’instruction, à laquelle on applique une extension de signe de 16 à 32 bits.

Le contenu du mot mémoire débutant à cette adresse est transféré dans le registre spécifié par le
champ « rt » de l’instruction.

Exemple : lw $s0, 8($sp) → On ajoute 8 à l’adresse contenue dans le registre $sp (pointeur de
pile) et on charge le contenu du mot mémoire correspondant dans le registre $s0.

L’instruction store word (sw) permet de stocker le contenu d’un registre dans un mot mémoire. Elle
consiste à réaliser l’opération suivante :

Mem[ R[rs]+SignExtImm ] = R[rt]

Exemple : sw $s0, 0($sp) → On ajoute 0 à l’adresse contenue dans le registre $sp (pointeur de
pile) et on sauvegarde le contenu du registre $s0 dans le mot mémoire correspondant.

On constate que pour réaliser ces deux instructions, le chemin de données utilisé pour les
instructions de type R doit être adapté.

• Le deuxième opérande de l’ALU est la constante spécifiée dans l’instruction. Un circuit


spécialisé réalise l’extension de signe (« sign-extend ») de cette constante de 16 à 32 bits.
• La sortie de l’ALU donne l’adresse de la mémoire des données à lire ou à écrire.
• Dans le cas d’un load, l’entrée Write data de la banque de registres est la donnée lue en
mémoire et l’entrée Write register doit correspondre au deuxième registre (R[rt]) spécifié
dans l’instruction.
• Dans le cas d’un store, l’entrée Write data de la mémoire de données est le contenu du
deuxième registre (R[rt]) spécifié dans l’instruction.

Pour choisir le bon type d’entrée en fonction de l’instruction exécutée, nous allons utiliser des
multiplexeurs. Nous avons vu à la section 4.2.2 qu’un multiplexeur est un circuit qui permet
d’aiguiller le signal d’une de ses N entrées vers sa sortie en fonction de la valeur d’un signal de
commande.

© HELMo Campus Guillemins Page 5.15


L’unité centrale de traitement (CPU) Architecture des ordinateurs - Théorie

Dans notre cas, il y a seulement deux entrées possibles. Un signal de contrôle (0 ou 1) permettra de
choisir la bonne entrée.

0 Si le signal de contrôle vaut 0 (inactif), le


M
U multiplexeur laisse passer l’entrée supérieure.
X
1 Si le signal de contrôle vaut 1 (actif), le
Signal multiplexeur laisse passer l’entrée inférieure.

On obtient le circuit suivant :

rs Read
register 1
Read ALUop
rt Read data 1 MemWrite
instruction register 2
zéro Mémoire données
Registres ALU MemToReg
M ALUsrc résultat Adresse
Write
U Read data M
rd register Read M
X U
data 2 U
RegDst X
Write X Write data
data
MemRead
RegWrite
const Sign-
extend

Figure 5-9 - Chemin de données pour les instructions de transfert mémoire

Les différents signaux de contrôle ont les fonctions suivantes.

• ALUop – Détermine l’opération effectuée par l’ALU.


• ALUsrc – Détermine si le deuxième opérande de l’ALU est le registre R[rt] ou la constante se
trouvant dans l’instruction (étendue sur 32 bits).
• MemWrite – Indique si l’opération écrit un résultat en mémoire (store).
• MemRead – Indique si l’opération lit une donnée en mémoire (load).
• MemToReg – Indique si la donnée à écrire dans le registre de résultat provient de la mémoire
ou du résultat de l’ALU.
• RegDst – Indique si le registre de résultat est R[rd] (instruction de type R) ou R[rt] (instruction
de type I).
• RegWrite – Indique s’il faut écrire ou non une donnée dans le registre de résultat.

Page 5.16 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie L’unité centrale de traitement (CPU)

5.3.6 Instructions de branchement


La dernière instruction à prendre en considération pour compléter notre chemin de données est
l’instruction de branchement beq. Sa définition est la suivante :

if (R[rs] == R[rt]) PC = (PC+4) + BranchAddress

L’adresse de branchement (BranchAddress) s’obtient en effectuant d’abord une extension de


signe à 32 bits de la constante signée de 16 bits présente dans l’instruction. On obtient ainsi le
décalage exprimé en nombre de mots. Pour obtenir le décalage exprimé en octets, il faut multiplier
ce nombre par 4, ce qui revient à décaler cette valeur de 2 bits vers la gauche.

Exemple : beq $0,$1,-25 → la constante spécifiée dans l’instruction vaut -25 (mots mémoire).

31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
Constante - - - - - - - - - - - - - - - - 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1
Extension Signe 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1
Décalage G de 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 0 0

Après extension de signe et décalage à gauche de 2 bits, la valeur obtenue est -100 (octets).

Pour compléter notre chemin de données, nous avons besoin d’un circuit qui réalise le décalage à
gauche de 2 bits (« shift left 2 »), ainsi que d’un additionneur pour calculer la nouvelle valeur de
compteur ordinal PC.

La nouvelle valeur du compteur ordinal sera égale à (PC+4 + BranchAddress) si la condition de


branchement est satisfaite, sinon elle sera égale à (PC+4) comme précédemment.

La sélection de la nouvelle valeur de PC est réalisée au moyen d’un multiplexeur. Ce multiplexeur est
contrôlé par la conjonction (ET) du signal zéro de l’ALU qui indique l’égalité des opérandes et du
signal de contrôle Branch qui indique une instruction de branchement beq.

Nous obtenons le chemin de données complet suivant :

M
Add U
X
4 Add
Shift
P Adresse rs Read left 2
C (read) register 1
Read ALUop Branch
Instruction MemWrite
rt Read data 1
Mémoire register 2
zéro Mémoire données
d’instructions Registres ALU MemToReg
M ALUsrc résultat Adresse
Write
U Read data M
rd register Read M
X U
data 2 U
RegDst X
Write X Write data
data
MemRead
RegWrite
const Sign-
extend

Figure 5-10 - Chemin de données complet

© HELMo Campus Guillemins Page 5.17


L’unité centrale de traitement (CPU) Architecture des ordinateurs - Théorie

5.3.7 Signaux de contrôle


Dans l’architecture MIPS, tous les signaux de contrôle excepté ALUop sont déduits directement à
partir de l’opcode de l’instruction, c’est-à-dire à partir des bits 31 à 26 du code machine de
l’instruction.

Nom du signal Format R lw sw beq


Entrée Opcode5 0 1 1 0
Opcode4 0 0 0 0
Opcode3 0 0 1 0
Opcode2 0 0 0 1
Opcode1 0 1 1 0
Opcode0 0 1 1 0
Sortie RegDst 1 0 X X
ALUSrc 0 1 1 0
MemToReg 1 0 X X
RegWrite 1 1 0 0
MemRead 0 1 0 0
MemWrite 0 0 1 0
Branch 0 0 0 1
ALUop1 1 0 0 0
ALUop2 0 0 0 1
Figure 5-11 - Signaux de contrôle

Le signal ALUop est quant à lui déduit de l’opcode et du code de fonction (bits 5 à 6).

5.3.8 Instructions de saut de type J


Le seul type d’instruction dont nous n’avons pas tenu compte est le saut inconditionnel (jump) qui
correspond au format J.

Nous vous laissons le soin, à titre d’exercice, d’imaginer comment compléter le schéma de la Figure
5-10. Les éléments à prendre en considération sont les suivants :

• Un signal de contrôle Jump indiquera si l’instruction est un saut inconditionnel.


• Le saut est inconditionnel, il n’y a donc aucune condition évaluée par l’ALU.
• L’adresse de saut est composée des 4 bits de poids fort de (PC+4), suivis des 26 bits d’adresse
présents dans l’instruction, suivis de deux bits à zéros.
Suggestion : pour obtenir les 28 derniers bits, on peut décaler de 2 bits vers la gauche la
constante sur 26 bits.
• Un multiplexeur supplémentaire permet d’aiguiller cette nouvelle adresse vers le registre PC
si le signal Jump est actif.

5.3.9 Synchronisation du CPU


Jusqu’à présent, nous n’avons pas évoqué les aspects temporels du circuit. La solution la plus simple
consiste à réaliser une implémentation dans laquelle chaque instruction est exécutée en un seul
cycle d’horloge.

Page 5.18 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie L’unité centrale de traitement (CPU)

Lors de la transition montante du signal d’horloge, l’instruction située à l’adresse contenue dans le
compteur ordinal (PC) est lue en mémoire. Cette instruction est alors exécutée.

L’écriture d’une donnée en mémoire, le stockage d’un résultat dans un registre et la mise à jour du
compteur ordinal (PC) s’effectuent sur la transition descendante du signal d’horloge. De cette
manière, on évite de modifier les données d’entrée pendant l’exécution de l’instruction.

Cette simplicité a un coût : le cycle d’horloge étant le même pour toutes les instructions, il doit donc
être supérieur ou égal au temps nécessaire à l’exécution de l’instruction la plus lente. Dans notre cas,
l’instruction la plus lente est l’instruction load (lw) qui nécessite 5 étapes : accès en lecture à la
mémoire d’instructions, accès en lecture aux registres, calcul de l’adresse mémoire effective avec
l’ALU, accès en lecture à la mémoire de données et écriture dans un registre.

Par contraste, une instruction de type R ne nécessite pas d’accès (lent) à la mémoire de données.
Enfin, une instruction de saut inconditionnel est la plus rapide puisqu’elle n’utilise ni les registres, ni
la mémoire de données, ni même l’ALU.

La pénalité due à un design où toutes les instructions s’exécutent en un seul cycle d’horloge est
acceptable pour des jeux d’instructions très simples. Ce n’est plus le cas si on introduit des
opérations de calcul en virgule flottante ou d’autres opérations complexes (ex. calcul vectoriel), car
l’écart de temps entre l’instruction la plus simple et la plus complexe est alors très significatif.

5.4 Pipelining
5.4.1 Améliorer les performances
Lorsque l’on conçoit le chemin de données d’un processeur, on essaie évidemment d’optimiser au
mieux chacun des composants qui interviennent dans la chaîne de traitement (banque de registres,
mémoire, ALU, etc.) afin d’obtenir une performance maximale.

Il n’est toutefois pas possible d’optimiser indéfiniment la performance de ces composants. Pour
améliorer encore les performances, il faut mettre en œuvre d’autres stratégies qui consistent à
réaliser plusieurs tâches en parallèle. Nous allons nous intéresser à 2 d’entre elles :

1. Le pipelining, qui consiste à exécuter les instructions successives d’un même programme
simultanément.
2. Le traitement vectoriel, qui consiste à exécuter la même instruction sur plusieurs données
simultanément.

Dans les deux cas, il s’agit d’introduire du parallélisme au niveau de l’exécution des instructions d’un
programme unique (instruction-level parallelism) et pas d’exécuter plusieurs programmes
simultanément.

© HELMo Campus Guillemins Page 5.19


L’unité centrale de traitement (CPU) Architecture des ordinateurs - Théorie

5.4.2 Principe de fonctionnement


L’idée du pipelining est à rapprocher de celle du travail à la chaîne. Elle consiste à décomposer une
tâche complexe en une série de tâches plus simples, qui peuvent être exécutées à la suite l’une de
l’autre par des unités autonomes.

Supposons par exemple que l’on souhaite faire du pain. Les tâches à réaliser sont les suivantes :
A. peser et mélanger les ingrédients (10 min),
B. pétrir la pâte (20 min),
C. laisser monter la pâte (30 min),
D. cuire le pain (45 min),
E. laisser refroidir le pain (10 min),
F. couper et emballer le pain (5 min).

Le temps total pour réaliser notre pain est donc de 120 minutes. Si on souhaite réaliser plusieurs
pains, il suffit de répéter les opérations précédentes. On obtiendra donc un pain toutes les 2 heures.
Pain 1 A B C D E F
Pain 2 A B C D E F
Pain 3 A B C D E F
Figure 5-12 - Travail en séquence

On suppose que le matériel utilisé ne permet pas de réaliser une tâche donnée pour plus d’un pain à
la fois. Il est néanmoins possible d’améliorer la situation en enchaînant les tâches de manière
autonome. Ainsi, dès que les ingrédients du pain 1 sont pesés et mélangés (tâche A), ils sont versés
dans le pétrin (tâche B). On peut alors commencer à peser et à mélanger les ingrédients du pain 2
sans attendre la fin du processus complet. Et ainsi de suite… L’enchaînement des tâches est décrit
par le tableau suivant :
Pain 1 A B C D E F
Pain 2 A B C D E F
Pain 3 A B C D E F
Pain 4 A B C D E F
Pain 5 A B C D E F
Pain 6 A B C D E F
Figure 5-13 - Travail à la chaîne / Pipelining

Si on fabrique un grand nombre de pains, on voit qu’une fois la chaîne de fabrication lancée, chaque
unité de travail (A à F) est occupée avec un pain différent.
A. Pesage et mélange : pain N+5
B. Pétrissage : pain N+4
C. Levage : pain N+3
D. Cuisson : pain N+2
E. Refroidissement : pain N+1
F. Découpe et emballage : pain N

C’est le principe du pipelining.

Il est important de constater trois choses.

Page 5.20 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie L’unité centrale de traitement (CPU)

1. Le temps nécessaire pour passer d’un poste au suivant est conditionné par la tâche la plus
lente, à savoir la cuisson, qui dure 45 minutes.
2. Le temps total nécessaire pour fabriquer un pain est donc de 6 x 45 = 270 minutes.
3. En revanche, dès que le premier pain est fabriqué, on obtient un nouveau pain toutes les 45
minutes. En situation de régime, on peut donc produire 32 pains par 24h au lieu de 12.

Un pipeline ne diminue donc pas le temps total nécessaire à la réalisation d’une seule tâche ! Par
contre, il augmente le débit, c’est-à-dire le nombre de tâches réalisées par unité de temps. Le cas
idéal est celui où une tâche complexe peut être décomposée en N sous tâches de même durée. Dans
ce cas, un pipeline à N niveaux n’allongera pas le temps d’exécution de la tâche de départ et il
apportera un débit N fois plus important par rapport à organisation monolithique.

5.4.3 Mise en œuvre dans un CPU


Nous avons vu que l’exécution d’une instruction par notre processeur MIPS peut se décomposer en
une série de 5 tâches élémentaires :

1. Lire l’instruction en mémoire.


2. Décoder l’instruction (opcode) et lire le contenu des registres utilisés comme opérandes.
3. Exécuter l’opération demandée ou calculer une adresse.
4. Lire ou écrire une donnée en mémoire.
5. Ecrire une donnée ou un résultat dans un registre.

On peut donc envisager de créer un pipeline à 5 étages : 1 étage pour chacune des 5 tâches.

Pour mettre en œuvre la technique du pipeline, il faut aussi faire en sorte que chaque étape de
l’exécution d’une instruction puisse être réalisée indépendamment de la précédente et de la
suivante. Naïvement, on peut proposer l’approche illustrée à la figure suivante.

Lecture instruction Decodage/registres Exécution Accès mémoire Ecrit.

A B C D

Add

4 Add
Shift
M left 2
P Adresse rs Read
U
C (read) register 1
X
Read
Instruction rt Read data 1
Mémoire register 2
zéro Mémoire données
d’instructions Registres ALU
résultat Adresse
M Write
M
rd U register Read M
Read data
U
X data 2 U X
Write X Write data
data

const Sign-
extend

Figure 5-14 - Chemin de données avec pipeline

Le schéma précédent est une adaptation de celui de la Figure 5-10.

© HELMo Campus Guillemins Page 5.21


L’unité centrale de traitement (CPU) Architecture des ordinateurs - Théorie

Nous avons regroupé en 5 zones verticales clairement séparées les éléments qui correspondent à
chacune des phases du cycle d’exécution d’une instruction. Entre chaque phase, nous avons placé un
registre tampon (buffer). Son rôle est de stocker toutes les données générées au sein d’une phase
(ou provenant d’une phase précédente) qui seront utiles lors de la phase suivante (ou ultérieure).

Nous pouvons augmenter considérablement la vitesse de l’horloge, car le cycle d’horloge correspond
à présent au temps d’exécution de la phase la plus lente et non plus à celui d’une instruction
complète. Les données des registres tampons sont lues lors de la transition montante du signal
d’horloge et écrites lors de la transition descendante du signal d’horloge.

Principe de fonctionnement pour des instructions de type R

T1 :

Etage 1 L’instruction I1 est lue en mémoire et stockée dans le tampon A.

T2 :

Etage 1 L’instruction I2 est lue en mémoire et stockée dans le tampon A.


Etage 2 L’instruction I1 est décodée, les valeurs des registres d’opérandes sont lues et stockées
dans le tampon B, ainsi que le numéro du registre de résultat.

T3 :

Etage 1 L’instruction I3 est lue en mémoire et stockée dans le tampon A.


Etage 2 L’instruction I2 est décodée, les valeurs des registres d’opérandes sont lues et stockées
dans le tampon B, ainsi que le numéro du registre de résultat.
Etage 3 L’instruction I1 est exécutée par l’ALU, le résultat est stocké dans le tampon C. Le
numéro du registre de résultat est transféré du tampon B au tampon C.

T4 :

Etage 1 L’instruction I4 est lue en mémoire et stockée dans le tampon A.


Etage 2 L’instruction I3 est décodée, les valeurs des registres d’opérandes sont lues et stockées
dans le tampon B, ainsi que le numéro du registre de résultat.
Etage 3 L’instruction I2 est exécutée par l’ALU, le résultat est stocké dans le tampon C.
Etage 4 Pas d’accès mémoire pour l’instruction I1. Le résultat et le numéro du registre de
résultat sont transférés du tampon C au tampon D.

T5 :

Etage 1 L’instruction I5 est lue en mémoire et stockée dans le tampon A.


Etage 2 L’instruction I4 est décodée, les valeurs des registres d’opérandes sont lues et stockées
dans le tampon B, ainsi que le numéro du registre de résultat.
Etage 3 L’instruction I3 est exécutée par l’ALU, le résultat est stocké dans le tampon C.
Etage 4 Pas d’accès mémoire pour l’instruction I2. Le résultat et le numéro du registre de
résultat sont transférés du tampon C au tampon D.
Etage 5 Le résultat de l’instruction I1 est écrit dans le registre de résultat.
L’exécution de l’instruction I1 est terminée.

Page 5.22 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie L’unité centrale de traitement (CPU)

Et ainsi de suite… Une fois que le pipeline est rempli, il constate qu’il y a 5 instructions exécutées
simultanément. Notre pipeline permet donc théoriquement de multiplier le débit par 5.

Rappelons qu’avec la technique du pipeline, le temps d’exécution d’une seule instruction n’est pas
plus court. Il peut même être plus long. Par contre, le pipeline permet de démarrer l’exécution de
l’instruction suivante sans attendre que l’exécution de l’instruction précédente soit terminée, ce qui
permet d’augmenter le débit, c’est-à-dire le nombre d’instructions exécutées par seconde.

5.4.4 Limitations du pipelining


Dans le cas idéal, un pipeline comportant N étages permet de multiplier le débit d’instructions par N.
Malheureusement, un pipeline n’est pas en mesure de travailler à 100% de sa capacité maximale en
permanence. Différents événements peuvent réduire sa performance maximale théorique. Nous
passons en revue ci-après les 3 problèmes les plus fréquents.

5.4.4.1 Dépendance de données entre deux instructions


Supposons que l’on veuille exécuter les instructions suivantes :

add $t0, $s0, $s1


add $t1, $t0, $s2

On constate que la deuxième instruction utilise le résultat de la première ($t0). Or, le résultat de la
première instruction ne sera stocké dans le registre de résultat $t0 que dans l’étage 5 du pipeline. En
attendant que cette donnée soit disponible, l’exécution de l’instruction 2 ne peut pas se poursuivre.
Il faut donc retarder artificiellement l’exécution de l’instruction 2 pour laisser le temps à l’instruction
1 de sortir du pipeline.

5.4.4.2 Conflit de ressources


Ce conflit survient lorsque deux étages du pipeline doivent accéder simultanément à une même
ressource matérielle. Ce serait par exemple le cas si les mémoires d’instructions et de données
n’étaient pas séparées, ou si toutes les additions de notre chemin de données étaient réalisées par
une ALU unique.

Le processeur doit alors gérer les priorités d’accès et arrêter certaines instructions le temps qu’une
autre termine son exécution et libère la ressource convoitée.

5.4.4.3 Branchement conditionnel


Lorsqu’une instruction de branchement conditionnel est exécutée, il faut attendre que la condition
de branchement soit évaluée et que l’adresse de branchement soit calculée pour pouvoir aller
chercher l’instruction suivante en mémoire. Pendant ce temps, le pipeline ne peut plus être alimenté
en instructions.

Tous les événements décrits ci-dessus induisent des retards dans le pipeline et donc une perte de
performance.

© HELMo Campus Guillemins Page 5.23


L’unité centrale de traitement (CPU) Architecture des ordinateurs - Théorie

Plus le pipeline est long et plus la probabilité qu’un tel événement survienne est grande. De même,
les retards engendrés sont proportionnels à la longueur du pipeline.

D’un autre côté, nous savons que le débit maximal théorique du processeur augmente avec le
nombre d’étages du pipeline.

Il faut donc trouver un juste compromis entre l’amélioration des performances et le coût des
pénalités. En pratique, dans de nombreux processeurs, la longueur du pipeline est comprise entre 10
et 15 étages. Le record est détenu par le processeur Intel Pentium 4 Prescott avec 31 étages !

5.4.5 Améliorations
Il existe heureusement de nombreuses techniques pour tenter de minimiser l’impact des problèmes
qui peuvent affecter le fonctionnement optimal d’un pipeline. Nous passons en revue les plus
courantes.

5.4.5.1 Le « data forwarding »


Cette technique est une optimisation matérielle qui consiste à modifier le chemin de données du
processeur pour rendre le résultat généré dans un étage du pipeline directement disponible pour un
étage précédent. On crée donc une sorte de raccourci interne au chemin de données qui permet de
réduire les retards d’exécution dans le cas d’une dépendance de données entre 2 instructions
successives.

5.4.5.2 L’exécution dans le désordre


Cette technique consiste à modifier l’ordre des instructions d’un programme de manière à en
optimiser l’exécution sans modifier le résultat final. Elle peut être utilisée pour réduire l’impact des
dépendances de données ou des conflits de ressources. L’idée directrice est : plutôt que d’attendre
sans rien faire, n’est-il pas possible de trouver des instructions à exécuter dans l’intervalle ?

Reprenons le programme de la section précédente auquel nous avons ajouté une troisième
instruction :

add $t0, $s0, $s1


add $t1, $t0, $s2
add $t2, $s0, 5

L’instruction 2 dépend du résultat de l’instruction 1 et va donc causer un retard dans le pipeline. En


revanche, l’instruction 3 est indépendante des 2 autres et peut donc être exécutée avant l’instruction
2 sans changer le résultat final du programme.

Le choix de la séquence d’exécution optimale peut être réalisé directement par le processeur en
temps réel, ce qui complique fortement la logique de contrôle, soit au moment de la compilation du
programme si le compilateur connaît les spécificités propres à l’architecture du processeur.

Page 5.24 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie L’unité centrale de traitement (CPU)

5.4.5.3 L’exécution spéculative


En temps normal, le pipeline est alimenté avec des instructions qui se suivent en mémoire.
Lorsqu’une instruction de branchement conditionnel est exécutée, ce n’est plus le cas. En principe, il
est nécessaire de connaître le résultat du branchement pour poursuivre l’exécution du programme.
L’idée à la base de l’exécution spéculative est d’essayer de prédire ce résultat et de poursuivre
l’exécution du programme en fonction de cette prédiction.

Lorsque le résultat réel du branchement est connu, soit la prédiction est confirmée et tout va bien,
soit la prédiction se révèle fausse et il faut alors annuler toutes les instructions déjà exécutées et
reprendre l’exécution du programme au bon endroit.

Les algorithmes de prédiction peuvent être très simples à très complexes. Par exemple, on peut
supposer tout simplement que le branchement sera toujours réalisé. Cette technique naïve peut
s’avérer étonnamment efficace pour un grand nombre de boucles, puisque le branchement a
effectivement lieu à chaque itération sauf à la dernière. Les algorithmes plus sophistiqués
maintiennent quant à eux des statistiques qui permettent d’atteindre des taux de prédictions
réussies de plus de 95% !

5.5 Processeur vectoriel


Une autre approche utilisée pour augmenter la puissance de calcul d’un processeur est l’approche
vectorielle. L’objectif de cette approche n’est pas d’exécuter plusieurs instructions simultanément
comme dans le cas du pipeline, mais bien d’exécuter une même instruction sur plusieurs données
simultanément.

Cette approche est particulièrement efficace pour traiter des algorithmes mathématiques qui
réalisent de nombreuses opérations sur des vecteurs ou des matrices : synthèse et traitement
d’images, calcul matriciel, traitement du signal, modélisation numérique, etc.

Pour atteindre son objectif, un processeur vectoriel :

• propose des instructions spécifiques (ex. addition de deux vecteurs) ;


• contient des registres vectoriels pouvant contenir N données scalaires (=simples) ;
• contient N unités de calcul identiques travaillant en parallèle sur chacune des données d’un
registre vectoriel.

5.6 Architecture super scalaire


Un processeur super scalaire multiplie les unités fonctionnelles du chemin de données de manière à
permettre l’exécution simultanée de plusieurs instructions sans provoquer de conflit de ressources. Il
utilise également la technique du pipeline pour son chemin de données principal.

Un tel processeur dispose de plusieurs unités de calcul (nombres entiers, nombres en virgule
flottante, vecteurs) et de plusieurs chemins d’accès à la mémoire. Il peut alors exécuter

© HELMo Campus Guillemins Page 5.25


L’unité centrale de traitement (CPU) Architecture des ordinateurs - Théorie

simultanément plusieurs instructions durant le même cycle d’horloge pour autant qu’elles utilisent
des unités fonctionnelles différentes. Par exemple, l’addition de 2 nombres entiers et la
multiplication de deux nombres en virgule flottante.

Chaque unité fonctionnelle peut à son tour utiliser un pipeline pour accélérer son fonctionnement
interne. Par exemple, l’addition de 2 nombres en virgule flottante peut se décomposer en 4 étapes :

• Comparer les exposants.


• Décaler la mantisse du nombre ayant le plus petit exposant.
• Additionner les mantisses.
• Normaliser le résultat.

Notons que, l’approche super scalaire reste pénalisée par les dépendances de données entre
instructions et par les instructions de branchement.

5.7 Exceptions et interruptions


5.7.1 Définitions
Dans la conception d’un processeur, c’est généralement la logique de contrôle qui est la partie la plus
complexe à mettre en œuvre. C’est particulièrement vrai lorsqu’on introduit des améliorations telles
que le pipelining, l’exécution dans le désordre, l’exécution spéculative, etc.

Dans sa version la plus simple, nous avons vu à la section 5.3.7 que la logique de contrôle du
processeur peut se résumer à implémenter une table de vérité. Il y a cependant deux éléments dont
nous n’avons pas encore tenu compte : les exceptions et les interruptions. Dans les deux cas, il s’agit
d’un événement, autre qu’une instruction de branchement ou de saut, qui va interrompre la
séquence normale d’exécution des instructions d’un programme.

Une exception est un événement imprévu dont la source est interne au processeur. Par exemple :

• Instruction inconnue.
• Erreur arithmétique (dépassement de capacité, division par zéro, …).
• Appel du programme au système d’exploitation.
• Problème matériel dans le processeur.

Une interruption est un événement imprévu dont la source est externe au processeur. Par exemple :

• Requête provenant d’un périphérique d’entrées/sorties.


• Problème matériel en dehors du processeur.

5.7.2 Gestion des exceptions et des interruptions


La gestion des exceptions et des interruptions est similaire. Lorsqu’un tel événement se produit, le
processeur doit au minimum :

Page 5.26 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie L’unité centrale de traitement (CPU)

1. Sauvegarder l’adresse de l’instruction en cours d’exécution dans un registre spécial appelé


EPC (Exception Program Counter), c’est-à-dire le compteur ordinal d’exception.
2. Transférer le contrôle au système d’exploitation en exécutant un sous-programme de gestion
d’exceptions situé à une adresse prédéfinie.
3. Le système d’exploitation évalue la cause de l’événement et décide de l’action appropriée à
prendre :
• Exécuter une tâche d’entrée/sortie (lors d’une interruption d’entrée/sortie).
• Réaliser une action prédéfinie, telle que renvoyer la valeur NaN (Not a Number) en
cas de dépassement de capacité.
• Terminer l’exécution du programme et informer l’utilisateur de l’erreur.
• Poursuivre l’exécution du programme.
• Etc.
4. Si l’exécution du programme est poursuivie, le système d’exploitation utilise le contenu du
registre EPC pour déterminer où l’exécution doit reprendre.

Pour déterminer l’action appropriée à prendre, le système d’exploitation doit connaître la nature de
l’exception ou de l’interruption.

Deux techniques sont utilisées :

1. La logique de contrôle du processeur stocke un code indiquant la cause de l’exception dans


un registre de statut réservé pour cet usage. Le système d’exploitation consulte le contenu
de ce registre pour décider de l’action à réaliser.
2. L’adresse du sous-programme du système d’exploitation auquel la gestion de l’exception est
transférée est choisie en fonction de la cause de l’exception. Le système d’exploitation
déduit donc cette cause en fonction du sous-programme qui a été appelé. On parle alors
d’interruptions vectorisées, car les adresses des différents sous-programmes se trouvent
dans un tableau (vecteur) d’adresses.

La gestion des exceptions dans un processeur réel avec pipeline et/ou d’autres améliorations est bien
évidemment nettement plus complexe à mettre en œuvre.

Au moment où une exception survient, plusieurs instructions sont en cours d’exécution. Comment
déterminer l’instruction concernée ? Faut-il terminer l’exécution des instructions partiellement
exécutées ou les annuler complètement ? Faut-il vider le pipeline avant de transférer le contrôle au
système d’exploitation ?

La réponse à toutes ces questions détaillées sort du cadre de ce cours. Le lecteur intéressé consultera
avec profit l’ouvrage de référence « Computer Organization and Design », David A. Patterson & John
L. Hennessy, Ed. Morgan Kaufmann ».

© HELMo Campus Guillemins Page 5.27


L’unité centrale de traitement (CPU) Architecture des ordinateurs - Théorie

Page 5.28 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Les mémoires

66 Les mémoires
6.1 La hiérarchie des mémoires
Note : le contenu de ce chapitre est en partie basé sur celui de chapitre 7 du livre « Architecture et
technologie des ordinateurs, P. Zanella, Y. Ligier, E. Lazard, 5e édition, éditions Dunod ».

Après le CPU, la mémoire est un des éléments les plus fondamentaux de tout ordinateur. En effet,
nous avons besoin de mémoire pour stocker les instructions des programmes, ainsi que les données
sur lesquelles ils travaillent.

On pourrait rêver d’un ordinateur idéal dans lequel la quantité de mémoire serait illimitée et l’accès
à n’importe élément stocké dans cette mémoire infiniment rapide. Malheureusement, la réalité
technique est tout autre :

1. La capacité de stockage d’une mémoire, même si elle est très grande, est toujours limitée.
2. La vitesse d’accès à un élément en mémoire dépend de la technologie utilisée pour fabriquer
celle-ci.

Les limitations technologiques et les contraintes de coût font que ces deux aspects sont
généralement antagonistes :

• Les mémoires très rapides utilisent une technologie coûteuse et seront généralement de
faible capacité.
• Les mémoires de très grande capacité utiliseront quant à elles des technologies moins
coûteuses, mais plus lentes.

En pratique, on doit donc trouver un compromis entre le coût, la capacité et la performance. Suivant
la nature des données à stocker, l’usage qui en est fait et la fréquence de leur utilisation, on aura
alors recours à différents types de mémoires.

Ces différentes mémoires constituent une hiérarchie dans laquelle chaque niveau peut échanger des
données avec les niveaux adjacents. Du point de vue du programme, cela permet de créer l’illusion
d’une mémoire unique dont la capacité est quasiment illimitée.

Les niveaux de la hiérarchie des mémoires sont les suivants :

• Registres – Petites mémoires extrêmement rapides situées au sein même du processeur. Les
registres servent à stocker les données directement manipulées par le processeur
(opérandes, résultats intermédiaires, compteur ordinal…)

© HELMo Campus Guillemins Page 6.1


Les mémoires Architecture des ordinateurs - Théorie

• Mémoire cache (antémémoire) – Mémoire très rapide, de capacité limitée, généralement


intégrée au processeur afin de réduire au maximum les temps d’accès. Elle sert de zone
tampon entre le processeur et la mémoire principale.
• Mémoire centrale – Mémoire principale utilisée pour stocker les programmes et les données
qu’ils manipulent. Il s’agit également d’une mémoire très rapide, mais utilisant malgré tout
une technologie moins rapide (et surtout moins coûteuse) que les registres ou la mémoire
cache, ce qui permet de disposer d’une grande capacité de stockage à un coût raisonnable.
Le temps d’accès est également nettement augmenté par le fait que cette mémoire n’est pas
intégrée au processeur.
• Mémoire de masse primaire – Cette mémoire est généralement constituée de disques
magnétiques ou de disques SSD (Solid-State Drive). Elle est destinée à stoker de grands
volumes de données de manière persistante, contrairement à la mémoire centrale qui perd
les données stockées lorsqu’elle n’est plus alimentée en courant électrique. La mémoire de
masse primaire offre un accès permanent et raisonnablement rapide aux données stockées.
• Mémoire de masse secondaire – Cette mémoire est destinée à stocker de façon persistante
de très grands volumes de données à un coût le plus faible possible. Elle est principalement
utilisée pour archiver des données ou pour effectuer des copies de sauvegarde de la
mémoire de masse primaire. Les technologies les plus utilisées sont les disques optiques (CD,
DVD, BluRay), les disques magnéto-optiques, les supports magnétiques (bandes, cassettes,
disques). L’accès aux données est lent à très lent, parfois séquentiel (bandes). Il peut même
nécessiter une intervention manuelle pour charger le support de stockage dans un lecteur.

Dans la hiérarchie des mémoires, la capacité de stockage augmente à chaque niveau, tandis que le
coût (par unité de donnée stockée) et la vitesse d’accès diminuent.

registres
s
nt

Ca
sa

mémoire cache
is

pa
cro

cit
éc
se
es

ro

mémoire centrale
vit

is
sa
&

nte
ix
Pr

mémoire de masse primaire

mémoire de masse secondaire

Figure 6-1 - La hiérarchie des mémoires

Page 6.2 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Les mémoires

6.2 Caractéristiques des mémoires


Les données stockées dans une mémoire sont organisées en entités plus ou moins importantes :
• Bit – Information binaire élémentaire (0 ou 1).
• Octet (byte) – Ensemble de 8 bits. L’octet constitue le plus souvent la plus petite quantité
d’information à laquelle il est possible d’accéder individuellement dans une mémoire au
moyen de son adresse.
• Mot (word) – Ensemble de plusieurs octets (le plus souvent 32 ou 64 bits). La taille d’un mot
mémoire correspond habituellement à la taille « standard » d’une donnée transférée entre la
mémoire et le processeur (largeur du bus de données), ou encore à la taille des registres du
processeur.

Pour les mémoires de masses, on rencontre aussi les notions de :


• Enregistrement (record) – Unité d’information dans un fichier ou une base de données
• Fichier (file) – Un ensemble d’enregistrements.
• Volume (volume) – Zone de stockage accessible comme un seul bloc et contenant des
fichiers.

Chaque type de mémoire possède un certain nombre de caractéristiques importantes.

• Adresse – Valeur numérique qui permet d’identifier l’emplacement d’une unité


d’information dans la mémoire. La taille d’une adresse détermine le nombre d’éléments
adressables individuellement. Par exemple, une adresse sur 32 bits permettra d’accéder à 232
= 4.294.967.296 éléments.
• Capacité – C’est le volume d’information, généralement exprimé en octets, que l’on peut
stocker dans une mémoire. Par exemple, une mémoire d’une capacité de 2 gigaoctets.

NOTE : lorsque les préfixes kilo-, méga-, giga-, etc. sont utilisés pour indiquer la capacité
d’une mémoire centrale, ils font en fait référence à la puissance de 2 la plus proche. Ainsi une
mémoire de 1 ko contient 210 = 1024 octets, 1 Go = 230 = 1.073.741.824 octets, etc. Les
capacités des disques magnétiques expriment quant à elles des puissances de 10. Ainsi, un
disque de 1 Go contient 109 = 1.000.000.000 octets. On constate qu’il y a une différence de
7% entre les deux définitions du Go !

Une nouvelle terminologie a été proposée afin de supprimer toute ambiguïté :

Nom Abréviation Valeur Nom Abréviation Valeur


kilooctet ko 103 kibioctet kio 210
mégaoctet Mo 106 mébioctet Mio 220
gigaoctet Go 109 gibioctet Gio 230
téraoctet To 1012 tébioctet Tio 240
pétaoctet Po 1015 pébioctet Pio 250
exaoctet Eo 1018 exbioctet Eio 260
zettaoctet Zo 1021 zébioctet Zio 270
yottaoctet Yo 1024 yobioctet Yio 280

Figure 6-2 - Préfixes décimaux et binaires

© HELMo Campus Guillemins Page 6.3


Les mémoires Architecture des ordinateurs - Théorie

• Temps d’accès – C’est le temps total nécessaire pour réaliser une opération de lecture ou
d’écriture en mémoire.
• Cycle mémoire – C’est le temps minimal qui doit s’écouler entre deux accès successifs à la
mémoire.
• Débit – C’est la quantité d’informations lues ou écrites par seconde. Par exemple, un disque
connecté au moyen d’une interface SATA 3 peut atteindre un débit de transfert maximum
théorique de 6 Gbits/s.
• Volatilité – C’est la capacité (ou non) d’une mémoire à conserver de façon permanente les
informations qui y sont stockées en l’absence d’énergie électrique. Ainsi, les registres, la
mémoire cache et la mémoire centrale sont des mémoires volatiles. Si on coupe le courant,
le contenu est perdu.
Par contre, les disques optiques et les supports magnétiques sont non volatiles. Il en va de
même pour la mémoire flash utilisée dans les clés USB.
• Type d’accès – Désigne la manière dont il est possible d’accéder à une information
particulière :
o Accès direct – On accède directement à l’information voulue sur base de son adresse
(ex. mémoire centrale). C’est l’accès le plus rapide.
o Accès séquentiel – On doit lire toutes les données stockées en commençant à la
première, jusqu’à atteindre celle qui est désirée (ex. bande magnétique). Ce type
d’accès est le plus lent.
o Accès semi-séquentiel – Il s’agit d’une combinaison des deux accès précédents. Par
exemple, on accède directement à un gros bloc d’informations au sein duquel la
donnée recherchée nécessite une lecture séquentielle.
o Accès par le contenu (mémoire associative) – Une telle mémoire organise
l’information en associant chaque valeur mémorisée à une clé d’identification
unique. Retrouver une information consiste donc d’abord à rechercher la clé dans la
mémoire associative puis à renvoyer la valeur associée à cette clé.

Une dernière caractéristique à laquelle nous nous intéressons est la disponibilité des informations.
Cette caractéristique concerne les mémoires de masse pour lesquelles il n’est pas toujours possible
ni utile de pouvoir accéder en permanence à la totalité des informations sauvegardées. On
distingue ainsi :

• Le stockage en ligne (online) – Les informations sont directement disponibles. Elles sont
stockées sur un dispositif qui est accessible en permanence, soit parce qu’il est raccordé
directement à l’ordinateur (disque dur, disque SSD, voir même un lecteur de DVD pour
autant qu’on ne retire pas le disque du lecteur), soit parce qu’il est accessible à travers un
réseau.
• Le stockage quasi en ligne (near-line) – Les informations font partie d’une bibliothèque de
type juke-box contenant un grand nombre de supports de stockage (disques, bandes,
cassettes) et un ou plusieurs dispositifs de lecture. Lorsqu’une information est demandée, le
système de commande du juke-box détermine en premier lieu sur quel support elle se
trouve. Un robot se charge d’aller chercher le support sélectionné dans la bibliothèque et de
le placer dans un des lecteurs disponibles. Le temps d’accès initial peut varier de quelques
secondes à plusieurs minutes (par exemple si aucun lecteur n’est disponible).

Page 6.4 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Les mémoires

• Le stockage hors ligne (offline) – Les supports contenant les informations sont stockés dans
une bibliothèque non automatisée. L’accès à cette bibliothèque peut être sécurisé
(confidentialité des données). Elle peut être localisée sur un autre site (plan catastrophe) et
aménagée pour assurer une longévité maximale des supports de données (température,
humidité, lumière).

6.3 Mémoire centrale


6.3.1 Classification des puces mémoires
Tous les circuits mémoires actuellement utilisés sont basés sur une technologie à base de semi-
conducteurs. La capacité de la mémoire centrale est souvent de l’ordre de quelques gigaoctets dans
un ordinateur personnel et peut atteindre quelques téraoctets dans les superordinateurs.

La mémoire centrale offre un accès direct aux données stockées sur base d’une adresse. On parle
aussi d’accès aléatoire, d’où le nom de mémoire RAM (Random Access Memory) donné à ce type de
mémoire.

Il va de soi que toutes les mémoires offrent un accès en lecture, sans quoi elles ne seraient pas très
utiles. Par contre, suivant la technologie utilisée, les cellules mémoire peuvent être écrites de
nombreuses fois, une seule fois ou pas tout. On distingue les types de mémoires suivants :

• RWM (Read-Write Memory) – Mémoire dont les cellules peuvent être lues et écrites de
nombreuses fois. On parle également de mémoire vive et parfois, par abus de langage, de
mémoire RAM.
• ROM (Read-Only Memory) – Mémoire dont les cellules peuvent être lues, mais pas
modifiées. On parle également de mémoire morte. Le contenu d’une telle mémoire est
déterminé une fois pour toutes par le fabricant.
• PROM (Programmable ROM) – Mémoire morte programmable une seule fois par l’utilisateur
et de manière irréversible.
• EPROM (Erasable Programmable ROM) – Mémoire morte reprogrammable un certain
nombre de fois. L’effacement de la mémoire en vue de sa reprogrammation nécessite une
exposition aux rayons ultraviolets durant ±30 minutes. Toute la mémoire est effacée.
• EEPROM (Electrically Erasable Programmable ROM) – Même principe que pour l’EPROM, si
ce n’est que l’effacement est électrique, sélectif et rapide (1 minute).
Note : la mémoire FLASH utilisée dans les cartes mémoires des appareils photo numériques,
dans les clés USB et maintenant dans les disques SSD est une forme améliorée d’EEPROM qui
permet d’offrir de meilleures performances tant en lecture qu’en écriture.

On voit, notamment avec la mémoire FLASH, que la distinction entre mémoire vive et mémoire
morte s’est fortement estompée du point de vue de l’utilisateur. Pourtant, en interne les différences
restent significatives : une mémoire FLASH nécessite d’effacer les cellules mémoires avant de pouvoir
écrire à nouveau dedans. De plus, le nombre de cycles effacement/écriture d’une cellule mémoire
est limité. Une fois ce nombre atteint, les blocs mémoires contenant des cellules « mortes » sont

© HELMo Campus Guillemins Page 6.5


Les mémoires Architecture des ordinateurs - Théorie

inutilisables, voire parfois la totalité de la puce mémoire. Ces contraintes nécessitent une gestion
assez sophistiquée de la mémoire flash pour garantir de bonnes performances et une longévité
maximale.

6.3.2 Mémoire vive statique ou dynamique


Parmi les mémoires vives actuellement utilisées, on distingue deux grandes catégories de mémoires :
la SRAM et la DRAM.

• SRAM (Static RAM) – Mémoire vive statique. Chaque cellule mémoire a une structure
similaire à celle d’une bascule D. Cette technologie est très rapide et consomme peu de
courant. Le qualificatif « statique » provient du fait que, tant que la mémoire est alimentée
en courant, son contenu est conservé indéfiniment sans devoir rien faire de particulier. Le
temps d’accès est de l’ordre de la nanoseconde ou moins. Elle est utilisée pour réaliser les
registres du processeur et la mémoire cache, là où une performance maximale est
nécessaire.

• DRAM (Dynamic RAM) – Mémoire vive dynamique. Chaque cellule mémoire utilise un
transistor et un petit condensateur. Le transistor charge ou décharge le condensateur suivant
qu’il faut stocker la valeur 1 ou 0. À la différence d’une SRAM, l’information stockée dans une
cellule de mémoire DRAM s’altère au fil du temps, car le condensateur se décharge
progressivement. Donc, même si le contenu de la mémoire n’est pas modifié, il est
nécessaire de rafraîchir régulièrement le contenu de chaque cellule afin de recharger le
condensateur des cellules qui contiennent la valeur 1. C’est ce qui explique le qualificatif
« dynamique » de ce type de mémoire. La nécessité de rafraîchir en permanence le contenu
de la mémoire rend la DRAM plus complexe et plus lente que la SRAM. Les temps d’accès
sont de l’ordre de quelques dizaines de nanosecondes. Par contre, comme chaque cellule
mémoire d’une DRAM n’utilise qu’un seul transistor et un condensateur, contre 6 transistors
ou plus dans le cas d’une SRAM, la densité d’intégration d’une DRAM est environ 4 fois plus
grande que celle d’une SRAM. Il est donc possible de fabriquer des puces de très grande
capacité à un coût nettement moins élevé.

Il existe plusieurs types de mémoires DRAM : FPM (Fast Page Mode), EDO (Extended Data
Output), SDRAM (Synchronous DRAM), DDR (Double Data Rate SDRAM), etc. Chaque
nouvelle génération de DRAM améliore principalement le débit des transferts de données
avec la mémoire.

Deux appellations coexistent pour identifier une barrette de DDR-SDRAM : DDR-xxx et PC-
xxx. L’appellation « DDR » (DDR, DDR2, DDR3, DDR4) fait référence au nombre de transferts
de données par seconde exprimé en MT/s. L’appellation « PC » (PC, PC2, PC3, PC4) fait quant
à elle référence au débit de données exprimé Mo/s et arrondi à la centaine la plus proche.

Dans une mémoire de type DDR (Double Data Rate), le nombre de transferts par seconde est
égal au double de la fréquence du bus système. Ainsi, si le bus système qui fonctionne à
1.600 MHz, on obtient une puce mémoire de type DDR4-3200. Et comme une puce DDR

Page 6.6 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Les mémoires

traite 64 bits de données à chaque transfert, le débit en Mo/s est égal à : ((<fréquence en
MHz> x 2 x 64) / 8). Pour notre bus à 1.600 MHz, le débit est donc de (1.600 x 2 x 64) / 8 =
25.600 Mo/s. Une puce DDR4-3200 est donc équivalente à une puce PC4-25600 et permet
d’atteindre un débit maximum de 25,6 Go/s !

6.3.3 Organisation physique


Un circuit mémoire est une puce dont la capacité maximale dépend de la technologie utilisée. Pour
réaliser une mémoire centrale de grande taille, on utilise un grand nombre de ces puces qui sont
réparties sur des cartes mémoires ou sur des barrettes (mini circuits imprimés) destinées à être
enfichées dans des connecteurs présents sur la carte mère de l’ordinateur.

Les barrettes de mémoire les plus courantes sont les barrettes SIMM (Single Inline Memory Module)
et DIMM (Dual Inline Memory Module). Il s’agit de petits circuits imprimés comportant généralement
8 ou 16 puces mémoires. Les barrettes SIMM disposent de 72 contacts et peuvent transférer 32 bits
de données par cycle d’horloge. Les barrettes DIMM disposent de 120 contacts sur chaque face du
circuit (240 au total) et sont capables de transférer 64 bits de données par cycle d’horloge. Il existe
un troisième type de barrettes imaginé spécifiquement pour les ordinateurs portables appelé SO-
DIMM (Small Outline DIMM), qui est une barrette DIMM caractérisée par un encombrement réduit.

Une barrette DIMM typique contiendra par exemple 8 puces mémoires de 256 Mo chacune, offrant
ainsi une capacité totale de 2 Go.

Il existe différentes façons de répartir les données entre les puces. On peut par exemple choisir de
répartir les 8 bits d’un octet en stockant un bit sur chaque puce, voire même 1 bit par carte/barrette.
Les différents morceaux de l’adresse permettront d’identifier le numéro de carte, de puce et
d’emplacement au sein de chaque puce pour reconstituer l’octet mémoire demandé.

Le choix d’une configuration mémoire particulière a toujours pour objectif d’essayer de maximiser le
débit des transferts de données avec la mémoire. Certains contrôleurs mémoires imposeront le
transfert de données par bloc plutôt qu’octet par octet afin d’augmenter encore le débit.

Une dernière technique, appelée entrelacement, consiste à répartir les mots mémoire successifs sur
des barrettes mémoires différentes, ce qui permet de lancer un accès mémoire sur le mot suivant
sans attendre la fin du cycle précédent, puisqu’on s’adresse à un circuit différent.

Nous renvoyons le lecteur intéressé par davantage de détails sur ces différents aspects de
l’organisation physique de mémoires vers les ouvrages de référence.

© HELMo Campus Guillemins Page 6.7


Les mémoires Architecture des ordinateurs - Théorie

6.4 Mémoire de masse


6.4.1 Les systèmes de stockage de masse
Les systèmes de stockage de masse ont deux objectifs principaux :

1. Offrir une capacité de stockage très importante à un coût réduit.


2. Assurer la conservation des informations sur une longue période de temps.

Il existe une grande variété de supports de mémoire de masse différents. Nous nous contentons de
lister les plus courants, sans entrer dans les aspects techniques de leur fonctionnement. Le lecteur
intéressé trouvera facilement de nombreux sites sur Internet qui décrivent ces systèmes de stockage
en détail.

• Supports papier : cartes et bandes perforées.


• Supports magnétiques : bandes, disquettes, disques durs, cartouches Zip, etc.
• Supports optiques : CD, DVD, BluRay.
• Mémoire flash : cartes mémoires, clés USB, disques SSD.

Les systèmes en ligne sont généralement basés sur des disques magnétiques qui permettent
d’accéder rapidement à de très grands volumes d’informations (base de données, serveurs de
fichiers, vidéothèque, etc.). Les systèmes d’archivage hors-ligne sont quant à eux plutôt basés sur des
bandes magnétiques ou des disques optiques qui sont beaucoup moins onéreux, mais aussi
nettement moins performants lorsqu’il s’agit d’accéder à une information stockée. Ces systèmes sont
indispensables pour pouvoir stocker les archives administratives d’un pays, ou encore sa production
littéraire, cinématographique, télévisuelle, etc. Dans notre société de l’information, cela représente
vite des volumes de plusieurs centaines, voire milliers de téraoctets!

Heureusement, les capacités et les densités de stockage d’informations ont progressé de manière
phénoménale depuis le début des années 1900. Pour s’en convaincre, il suffit de comparer, une carte
mémoire récente de type microSDXC avec le premier support de stockage de masse standardisé qui
était la carte perforée IBM de 80 colonnes :

• Une carte microSDXC récente permet de stocker 512Go de données dans une carte de
11x15mm, soit un volume total d’environ 158 mm3 et un poids de quelques grammes.
• Comme son nom l’indique, la carte perforée d’IBM permettait de stocker l’équivalent de 80
caractères alphanumériques sur une fiche cartonnée (165 gr/m2) de ±187x82mm.
• Pour stocker 512Go, il faudrait 6,8 milliards de cartes perforées, soit 3,4 millions de boîtes de
2000 cartes, ce qui représente un volume de stockage de l’ordre de 20.000 m3 et un poids
total approchant les 17.400 tonnes. En empilant toutes les cartes, on atteindrait une hauteur
de plus de 1200 km !

Page 6.8 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Les mémoires

6.4.2 Les disques magnétiques


Les disques magnétiques restent à l’heure actuelle le système de stockage de masse en ligne le plus
utilisé. Ils offrent un bon rapport prix/volume stocké et surtout une grande rapidité d’accès aux
informations.

A. Plateaux
B. Bras
C. Tête de lecture/écriture
D. Cylindre
E. Piste
F. Secteur : bloc de taille fixe (par exemple 512
octets)
Source : « Basic disk displaying CHS ».
Sous licence Public domain via Wikimedia Commons -
http://commons.wikimedia.org/wiki/File:Basic_disk_displaying_CHS.svg#
mediaviewer/File:Basic_disk_displaying_CHS.svg

Figure 6-3 - Structure d'un disque magnétique

Un disque dur se compose de plusieurs plateaux (disques) en aluminium superposés. Ces plateaux
tournent à une vitesse de plusieurs milliers de tours par minute. Chaque plateau est recouvert d’un
film constitué d’une substance magnétisable. Le stockage d’informations binaires est réalisé en
modifiant l’orientation des particules magnétiques à la surface du disque de façon à représenter les
valeurs 0 et 1. La lecture des informations consiste quant à elle à détecter le sens d’orientation des
particules magnétiques. Ces opérations sont réalisées au moyen de têtes de lecture/écriture situées
entre les plateaux.

Un disque dur possède une structure bien définie qui sert à répartir et surtout à pouvoir retrouver
par la suite les informations stockées :

• Chaque plateau est divisé en cercles concentriques, appelés pistes (tracks). Tous les plateaux
possèdent le même nombre de pistes.
• L’ensemble des pistes correspondantes de tous les plateaux constitue un cylindre (cylinder).
• Chaque piste est à son tour divisée en un certain nombre de secteurs (sectors). Un secteur
est un bloc de données de taille fixe, par exemple 512 octets.

Initialement, un disque dur ne contient pas cette structure. C’est l’opération de formatage qui va
créer les subdivisions nécessaires sur les différents plateaux du disque.

Historiquement, toutes les pistes d’un disque dur contenaient le même nombre de secteurs. Cette
structure très régulière présente l’avantage de permettre un calcul aisé de la position d’une
information sur le disque. Par contre, comme la longueur des pistes diminue lorsqu’on se rapproche
du centre d’un plateau, si on stocke la même quantité d’informations sur chaque piste, cela signifie

© HELMo Campus Guillemins Page 6.9


Les mémoires Architecture des ordinateurs - Théorie

que la densité linéaire des informations stockées est nettement plus grande au centre qu’à la
périphérie (cf. Figure 6-4 à gauche).

Les disques durs récents adoptent une organisation différente qui vise à garder une densité linéaire
constante et maximale sur toutes les pistes d’un plateau. Le nombre de secteurs par piste et la
quantité d’informations stockées augmentent au fur et à mesure que l’on s’écarte du centre du
disque. Cela complique un peu la tâche du contrôleur de disque, mais cela permet d’augmenter
significativement la capacité de stockage du disque. Cette technique porte le nom de Zoned Bit
Recording - ZBR (cf. Figure 6-4 à droite).

Figure 6-4 - Organisation des secteurs sur une piste

Pour lire ou écrire une information sur un disque dur, il faut donc déterminer le secteur auquel
accéder, mais aussi la piste et le plateau qui contiennent ce secteur. Chaque plateau possède sa
propre tête de lecture/écriture et est par conséquent accessible directement. Pour accéder à une
piste déterminée, la tête doit se déplacer pour atteindre la bonne position radiale sur le disque. Le
temps nécessaire pour effectuer ce déplacement porte le nom de temps de positionnement (seek
time). Toutes les têtes de lecture/écriture sont solidaires. On accède donc à la même piste
simultanément sur tous les plateaux, c’est-à-dire à un cylindre. Une fois la tête positionnée sur la
bonne piste, il faut attendre que le secteur souhaité passe sous la tête, ce qui demandera en
moyenne une demi-rotation du disque. Ce délai porte le nom de temps d’attente-rotation (rotational
latency). Il dépend de la vitesse de rotation du disque. Les données peuvent alors être lues ou écrites
à une vitesse maximale, ou encore taux de transfert maximum (burst rate), qui est fonction de la
vitesse de rotation du disque et de la densité de stockage des informations.

La vitesse maximale n’est d’application que pour le premier secteur lu et éventuellement pour un
certain nombre de secteurs additionnels, pour autant qu’ils se suivent sur une même piste ou au sein
d’un même cylindre, ce qui évite de devoir déplacer les têtes et/ou de subir un délai de rotation.

En pratique, le taux de transfert effectif sera nettement plus faible. Il va dépendre de la nature de
l’opération (lecture ou écriture) réalisée, de la taille des données à lire ou à écrire (beaucoup de
petits fichiers ou quelques gros), de la dispersion ou non des secteurs sur le disque (fragmentation),
de la performance du contrôleur de disque, de l’utilisation ou pas d’une mémoire cache, de la
performance de l’interface de connexion à l’ordinateur, etc.

Page 6.10 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Les mémoires

Le taux de transfert moyen est une indication du débit moyen qu’un disque dur est capable de tenir
sur une longue période de temps et prenant en considération les différents temps d’accès évoqués
ci-dessus pour un mix supposé représentatif de fichiers et d’opérations.

Différentes technologies sont utilisées pour connecter un disque dur à un ordinateur. Les interfaces
les plus connues sont les suivantes :

• IDE (Integrated Drive Electronics) – Technologie apparue au milieu des années 80 dont l’idée,
novatrice à l’époque, était de décharger le processeur central de la gestion du disque, en
plaçant l’électronique de gestion sur une carte séparée intégrée au disque. L’adresse d’un
secteur de 512 octets est spécifiée sur 20 bits et est le reflet direct de l’organisation du
disque (plateau/piste/secteur). La capacité maximale d’un disque est limitée à 504 Mo. La
vitesse de transfert maximale est de 4 Mo/s.
• EIDE (Extended IDE) – Évolution de la norme IDE qui introduit la notion d’adressage de bloc
logique (LBA – Logical Block Addressing). Chaque secteur est identifié par un numéro sur 28
bits qui est indépendant de l’organisation physique du disque. C’est le contrôleur qui
effectue la conversion en fonction de l’organisation interne choisie. La capacité maximale
d’un disque est limitée à 128 Go. La vitesse de transfert maximale est de 16,67 Mo/s.
• ATA (AT Attachement), également appelé PATA (Parallel ATA) – Évolution de la vitesse de
transfert avec l’ordinateur. Les données sont transférées en parallèle entre le disque et le
CPU (larges connecteurs et rubans de câbles plats).
• ATAPI (ATA Packet interface) – La vitesse de transfert évolue à chaque génération (33 Mo/s,
66Mo/s, 100 Mo/s). La norme ATAPI-6 augmente également la taille de l’adresse d’un
secteur à 48 bits, autorisant de la sorte une capacité maximale de 128 pétaoctets !
• SATA (Serial ATA) – Le changement majeur est le transfert des données en série vers le
processeur, plutôt qu’en parallèle, ce qui permet d’accroître considérablement la vitesse de
transfert. La norme initiale a été conçue pour un débit maximal théorique de 1,5 Gbit/s. La
norme SATA II est passée à 3 Gbit/s, la norme SATA III à 6 Gbit/s (voire 16 Gbit/s avec la
révision 3.2). En pratique, le débit réel est de l’ordre de 150/300/600 Mo/s suivant la version
utilisée (1969 Mo/s en version 3.2).
• SCSI (Small Computer System Interface) – Interface permettant la connexion de maximum 7
périphériques (disque dur, scanner, DVD-ROM, …) à un bus de données partagé. Les
périphériques sont raccordés en série. Le succès de l’interface SCSI provient de ses vitesses
de transfert très élevées (640 Mo/s) qui en ont fait l’interface de choix pour les stations de
travail haut de gamme et pour les serveurs. De nos jours, l’interface SCSI a disparu des
ordinateurs grand public au profit du SATA ou de l’USB. Elle reste cependant très utilisée
dans le monde professionnel, avec des évolutions ultrarapides telles que le Fibre Channel qui
propose déjà des débits de 3,2 Go/s !

© HELMo Campus Guillemins Page 6.11


Les mémoires Architecture des ordinateurs - Théorie

6.4.3 Le système RAID


6.4.3.1 Introduction
La motivation historique qui a mené à la conception du système RAID était le besoin de trouver une
alternative aux disques durs de grande capacité qui étaient extrêmement coûteux.

L’idée à la base du système est très simple : elle consiste à connecter plusieurs disques de faible
capacité (et donc peu coûteux) afin de créer un ensemble de grande capacité (appelé grappe) qui est
vu par l’ordinateur hôte comme un seul disque logique.

La signification initiale de l’acronyme RAID était « Redundant Array of Inexpensive Disks », c’est-à-
dire « groupement redondant de disques peu onéreux ». Actuellement, le « I » signifie
« Independent », c’est-à-dire « indépendants ». Ce changement de nom reflète l’évolution de la
finalité première du système RAID. En effet, avec l’évolution des technologies, l’objectif initial qui
était d’augmenter la capacité en réduisant le coût est devenu moins critique et a cédé la place aux
autres bénéfices de la technologie RAID, à savoir que l’utilisation de plusieurs disques indépendants
permet d’accroître la performance et/ou la tolérance aux pannes du système de stockage.

6.4.3.2 Les bénéfices du système RAID


Outre l’accroissement éventuel de la capacité totale de stockage du système, les deux objectifs
techniques principaux du système RAID sont :

• L’augmentation des performances, c’est-à-dire des vitesses de lecture et d’écriture.


• Une meilleure tolérance aux pannes grâce à la redondance des données.

Le système RAID propose plusieurs méthodes standardisées pour organiser les données sur les
différents disques. On les appelle « niveaux RAID », bien qu’il n’y ait pas de hiérarchie entre eux. Les
niveaux les plus connus sont les niveaux 0 à 5.

(Toutes les figures de cette section proviennent de « https://en.wikipedia.org/wiki/Standard_RAID_levels » et sont attribuées à


en :User :Cburnett, User:knakts)

• RAID 0 – L’objectif premier du niveau 0 est de regrouper plusieurs


disques physiques pour créer un volume logique de grande capacité.
On profite également du fait que l’on dispose de plusieurs disques
physiques pour améliorer les performances globales du système. Pour
y arriver, les données sont réparties de telle sorte que la lecture ou
l’écriture des secteurs consécutifs d’un gros fichier est réalisée de
manière circulaire sur les différents disques durs. Si on dispose de N
disques, on peut donc effectuer N opérations d’entrées/sorties en
parallèle. Pour obtenir une performance maximale, l’organisation des
données doit être identique sur tous les disques, ce qui permet Figure 6-5 - Raid 0
d’équilibrer la charge entre les disques. Pour cette raison, si on utilise
N disques de capacités différentes, la capacité totale de la grappe est égale à N fois la
capacité du disque le plus petit. Le niveau 0 n’offre aucune tolérance aux pannes. Au

Page 6.12 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Les mémoires

contraire, il diminue la fiabilité globale du système puisqu’il suffit qu’un seul des N disques
tombe en panne pour perdre la totalité des données !

• RAID 1 – Le niveau 1 offre une tolérance aux pannes en dupliquant les


données de chaque disque sur un disque miroir. Une grappe RAID 1
contient donc un nombre pair de disques. La capacité totale de
stockage est égale à (N x capacité la plus petite)/2.
Lors de l’écriture, chaque secteur doit être écrit 2 fois (disque primaire
+ miroir). L’écriture est soit simultanée sur les 2 disques (duplexing),
soit réalisée en 2 temps : d’abord sur le disque primaire, puis recopie
sur le disque secondaire (mirroring). La performance en écriture est
donc au mieux celle d’un disque unique. En lecture, la performance
peut être doublée, car chaque disque dispose des mêmes données. On Figure 6-6 - Raid 1
peut donc lire un secteur sur l’un ou l’autre disque et donc lire 2
secteurs en parallèle. Lorsqu’un des deux disques d’une paire tombe en panne, les données
restent disponibles sur le second. Elles sont recopiées sur le disque de remplacement.

• RAID 2 – Ce niveau n’est plus utilisé. Il utilisait un code de Hamming pour protéger les
données contre la perte d’un disque. L’amélioration des performances en lecture/écriture
est obtenue en stockant chaque bit d’un octet (ou mot) de données sur 1 disque différent.

Figure 6-7 - Raid 2

• RAID 3 – Le niveau 3 est une version simplifiée du niveau 2. Les données sont toujours
réparties bit par bit sur les différents disques, mais la protection des données est réalisée en
ajoutant simplement un bit de parité (et donc un disque). Si un disque tombe en panne et est
remplacé, tous les bits du disque de remplacement sont initialement à zéro. Si la vérification
de parité d’un mot est incorrecte, on sait que le bit correspondant sur le disque de
remplacement doit valoir 1.

Figure 6-8 - Raid 3

© HELMo Campus Guillemins Page 6.13


Les mémoires Architecture des ordinateurs - Théorie

• RAID 4 – Les données sont écrites bloc par bloc de manière circulaire sur les N disques (cf.
niveau 0) et non plus bit par bit comme pour les niveaux 2 et 3. La protection des données
est obtenue en calculant un bloc de parité pour chaque groupe de N blocs. Ce bloc de parité
est stocké sur le disque N+1. La limitation principale de ce système est que chaque fois qu’un
secteur est modifié, il faut également recalculer et écrire le bloc de parité correspondant. Le
disque de parité constitue vite un goulot d’étranglement si les données sont mises à jour
fréquemment.

Figure 6-9 - Raid 4

• RAID 5 – Petite amélioration du niveau 4 qui consiste à répartir les blocs de parité sur les
différents disques de manière circulaire afin de limiter le goulot d’étranglement. En cas de
panne, la reconstruction du disque de remplacement est un processus complexe.

Figure 6-10 - Raid 5

La gestion d’une grappe RAID peut être réalisée par voie logicielle ou matérielle.

Certains niveaux RAID peuvent être combinés entre eux. Par exemple, une grappe RAID 0 peut être
dupliquée en miroir, on parle alors de RAID 01 (ou RAID 0+1).

Page 6.14 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Les mémoires

6.4.4 Architectures de stockage


L’évolution des réseaux de communication permet d’envisager une délocalisation du système de
stockage de masse par rapport à l’ordinateur qui l’utilise. Nous terminons cette section en donnant la
définition de trois architectures de stockage couramment rencontrées de nos jours.

• DAS (Direct Attached Storage) – C’est l’architecture standard dans laquelle le système de
stockage est directement raccordé au serveur qui l’utilise.
• NAS (Networked Attached Storage) – Littéralement, il s’agit d’un système de stockage
connecté à un réseau, c’est-à-dire en fait un serveur disposant d’un système de stockage
local et raccordé à un réseau. Lorsqu’une application souhaite accéder aux données se
trouvant sur un NAS, elle envoie une requête au serveur distant en utilisant un protocole de
gestion de fichiers standard (NFS, AFP, …). Le serveur distant accède au système de stockage
et renvoie les données demandées à l’application cliente.
• SAN (Storage Area Network) – Un réseau de stockage n’est ni un système de stockage ni un
serveur de données. C’est une manière de partager des ressources de stockage de très
grande capacité entre plusieurs serveurs au moyen d’un réseau de communication
ultrarapide qui interconnecte les serveurs et les disques. Chaque serveur voit l’espace disque
qui lui est alloué comme s’il s’agissait d’un disque dur qui lui est directement attaché. L’accès
aux données s’effectue par bloc (secteur) comme pour un disque dur classique et non par
fichier.

Ces différentes architectures sont complémentaires. NAS et SAN utilisent également la


technologie RAID.

© HELMo Campus Guillemins Page 6.15


Les mémoires Architecture des ordinateurs - Théorie

6.5 Mémoire cache (antémémoire)


6.5.1 Introduction
Nous avons expliqué en présentant la hiérarchie des mémoires que les caractéristiques attendues
d’un circuit mémoire sont souvent contradictoires. Ainsi, la rapidité s’obtient généralement au
détriment du coût et de la capacité.

Le processeur dispose de registres très rapides auxquels il a un accès direct, mais ceux-ci sont en
nombre limité et ne stockent qu’un seul mot mémoire. La mémoire centrale offre quant à elle une
grande capacité de stockage, mais elle utilise une technologie plus lente (DRAM) et présente un
temps d’accès moyen qui est très long par rapport à la durée du cycle d’instruction du processeur.

Une mémoire cache est un circuit mémoire très rapide (SRAM) et de capacité limitée. Il est placé
entre le processeur et la mémoire centrale. L'objectif est d’utiliser cette mémoire intermédiaire pour
y stocker les instructions et les données les plus utilisées. Cela permet de réduire au maximum le
nombre d’accès à la mémoire centrale et de limiter par conséquent l’impact de ces accès très lents.

Les processeurs modernes possèdent généralement plusieurs niveaux de mémoire cache. Par
exemple, l’architecture Sandy Bridge d’Intel possède 3 niveaux de cache :

• Cache de niveau 1 (L1) – Mémoire de 64 Ko, directement intégrée à chaque cœur. Pour être
tout à fait précis, cette mémoire cache est divisée en 2 morceaux : 32 Ko pour les
instructions et 32 Ko pour les données. Un accès demande 4 cycles d’horloge.
• Cache de niveau 2 (L2) – Mémoire de 256 Ko, directement intégrée à chaque cœur. Un accès
demande 11 cycles d’horloge. Mémoire cache commune (unified cache) pour les instructions
et les données.
• Cache de niveau 3 (L3) – Mémoire de 1 Mo à 20 Mo suivant les versions du processeur. Elle
se trouve sur la carte mère. Elle est partagée entre tous les cœurs et est aussi utilisée par le
processeur graphique.

Chaque niveau communique exclusivement avec le niveau précédent ou suivant de la hiérarchie.

Ainsi, lorsque le CPU a besoin d’une donnée, il interroge la mémoire cache de niveau 1. Si la donnée
n’est pas disponible, la mémoire cache de niveau 1 fait appel à celle de niveau 2. Celle de niveau 2 à
celle de niveau 3. Et finalement, la mémoire cache de niveau 3 va chercher l’information demandée
en mémoire centrale.

Page 6.16 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Les mémoires

6.5.2 Le principe de localité


Le fonctionnement efficace des mémoires caches est basé sur le principe de localité qui stipule que :

• Si un programme utilise une donnée (ou une instruction) située dans un emplacement
mémoire, il aura aussi tendance à utiliser peu après les données (ou instructions) situées à
proximité. On parle dans ce cas de localité spatiale.
• Si un programme utilise une donnée (ou une instruction), il aura tendance à réutiliser cette
donnée (ou instruction) dans un futur proche. On parle alors de localité temporelle.

La pertinence du principe de localité découle de la manière dont les programmes sont conçus et
exécutés, ainsi que de la façon dont les données sont stockées en mémoire.

Ainsi, si on considère un sous-programme qui trie un tableau de nombres, les données du tableau
sont généralement stockées dans une zone mémoire d’un seul tenant. Il en va de même pour les
instructions du sous-programme. Il en résulte une localité spatiale lors de l’exécution.

Par ailleurs, l’algorithme de tri va répéter plusieurs fois les mêmes séquences d’instructions (boucles)
et accéder de façon répétée aux éléments du tableau. Il en résulte une localité temporelle lors de
l’exécution.

Le lien entre le principe de localité temporelle et l’efficacité d’une mémoire cache est assez simple à
comprendre : lorsqu’une donnée (ou instruction) est utilisée, elle est placée dans la mémoire cache.
Si la même donnée (ou instruction) est utilisée à nouveau peu de temps après, elle est probablement
toujours présente dans la mémoire cache.

En ce qui concerne le principe de localité spatiale, l’idée est que si un mot mémoire doit être placé en
mémoire cache, alors on ne transfère pas uniquement ce mot isolé, mais bien tout un bloc auquel il
appartient. De cette façon, si le programme doit accéder au mot mémoire suivant ou précédent, il
sera probablement déjà dans la mémoire cache. Un tel bloc porte le nom de ligne de cache (cache
line). À titre d’exemple, l’architecture Sandy Bridge utilise des lignes de 64 octets.

6.5.3 Fonctionnement d’une mémoire cache


6.5.3.1 Généralités
Pour expliquer le fonctionnement d’une mémoire cache, nous allons supposer qu’il n’y a qu’un seul
niveau de cache. Notre mémoire cache est située entre le processeur et la mémoire centrale.

Les principes exposés restent valables s’il y a plusieurs niveaux de cache, puisque chaque niveau
communique uniquement avec les deux niveaux directement adjacents.

Une mémoire cache est divisée en un certain nombre de lignes (blocs de données) contenant par
exemple 64 octets. Chaque ligne de la mémoire cache peut accueillir la copie d’un bloc de données
de même taille provenant de la mémoire centrale.

© HELMo Campus Guillemins Page 6.17


Les mémoires Architecture des ordinateurs - Théorie

Considérons un système qui a les caractéristiques suivantes :

• La mémoire centrale a une taille de 64 Ko (=216 octets).


o Elle utilise donc des adresses sur 16 bits.
• Les lignes de la mémoire cache ont une taille fixe de 64 octets (=26).
o L’adresse de début d’un bloc en mémoire centrale est un multiple de 64 et se
termine donc toujours par 6 bits à 0.
o Tous les octets qui font partie d’un bloc ont une adresse qui commence par les
mêmes 10 premiers bits.
• La mémoire cache a une capacité de 1024 octets.
o Elle permet de stocker 16 lignes (=24) de 64 octets.
o L’index d’une ligne dans la mémoire cache aura une taille de 4 bits.

La gestion de la mémoire cache implique un certain nombre de tâches.

• Lorsque le processeur souhaite accéder en lecture ou en écriture à une adresse mémoire, il


faut déterminer si le bloc de données correspondant est déjà présent en cache ou pas.
• Lorsqu’un bloc de données est transféré depuis la mémoire centrale vers la mémoire cache,
il faut décider dans quelle ligne de la mémoire cache il sera stocké (correspondance ou
mapping en anglais).
• Si toutes les lignes de la mémoire cache sont occupées, quelle stratégie doit-on utiliser pour
déterminer quel bloc doit être remplacé ?
• Lorsqu’une donnée est modifiée dans la mémoire cache, il faut veiller à mettre à jour la
mémoire centrale.

6.5.3.2 Cache à correspondance directe (direct-mapped cache)


La méthode la plus simple pour choisir la ligne à utiliser dans la mémoire cache est de se baser sur
l’adresse du bloc en mémoire centrale. On réalise l’opération suivante :

Index de ligne = (adresse bloc) modulo (nombre de lignes)

La figure suivante illustre ce principe pour une mémoire cache contenant 4 lignes.

0
1
2
3
0 4
1 5
2 6
3 7
8
9
10
11

Figure 6-11 - Cache à correspondance directe

Page 6.18 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Les mémoires

Exemple : on souhaite accéder au contenu de l’adresse mémoire 46.323 et cette donnée n’est pas
encore présente dans la mémoire cache.

Adresse mémoire : 46.323 → 1011010011110011 en binaire.


Adresse du bloc : on laisse tomber les 6 bits de poids faible → 1011010011xxxxxx.

On va donc transférer les 64 octets compris entre les adresses 1011010011000000 (46.272) et
1011010011111111 (46.335) dans une ligne de la mémoire cache.

Puisque la mémoire cache peut contenir 16 lignes, on calcule « (adresse bloc) modulo 16 », ce qui
revient à garder les 4 derniers bits de l’adresse du bloc, c’est-à-dire 0011. Notre bloc de données sera
donc transféré dans la ligne 3 de la mémoire cache.

Adresse mémoire
1 0 1 1 0 1 0 0 1 1 1 1 0 0 1 1
Adresse bloc Index octet
1 0 1 1 0 1 0 0 1 1
Étiquette (tag) Index cache

Avec cette méthode de correspondance, tous les blocs de données dont l’adresse se termine par
‘0011’ utiliseront la ligne 3 de la mémoire cache. Comment savoir si celui qui nous intéresse est
effectivement présent dans la mémoire cache ou pas ?

La mémoire cache est structurée de la manière suivante :

Index Valide Tag Données (64 octets par ligne)


0000 Non -
0001 Non -
0010 Non -
0011 Oui 101101 Mém[101101 0011 000000] → Mém[101101 0011 111111]
...
1111 Non -

Pour chacune des 16 lignes de données, la mémoire cache stocke les informations suivantes :

• Valide – Bit qui indique si la ligne de cache est utilisée ou non.


• Tag – Préfixe de 6 bits de l’adresse du bloc qui est effectivement en cache. L’adresse
complète du bloc est obtenue en concaténant ce préfixe avec l’index de la ligne.
• Données – Les 64 octets de données du bloc mémoire transféré en cache.

Lorsque le processeur souhaite accéder au contenu d’une adresse mémoire, le gestionnaire de cache
décompose l’adresse de 16 bits demandée comme suit :

• Bits 15 à 10 = tag
• Bits 9 à 6 = index de ligne
• Bits 5 à 0 = index de l’octet au sein de la ligne

© HELMo Campus Guillemins Page 6.19


Les mémoires Architecture des ordinateurs - Théorie

On a alors les 3 possibilités suivantes :

1. Le bit de validité de la ligne de cache est égal à 0 (non) : la donnée n’est pas dans le cache.
2. Le bit de validité de la ligne de cache est égal à 1 (oui), mais le tag extrait de l’adresse est
différent de celui stocké dans la mémoire cache : la donnée n’est pas dans le cache.
3. Le bit de validité vaut 1 (oui) et les deux tags sont identiques : la donnée est présente dans le
cache. On utilise l’index de ligne et l’index d’octet pour obtenir la donnée voulue.

Lorsque l’adresse accédée n’est pas en mémoire cache, on parle d’un défaut de cache (cache miss).
Lorsqu’elle est présente en mémoire cache, on parle d’un succès de cache (cache hit).

La correspondance entre l’adresse d’un bloc en mémoire et l’index de la ligne de cache où il doit être
stocké étant fixe, le contenu d’une ligne de cache est remplacé dès l’instant où un bloc ayant le
même index de ligne doit être transféré vers le cache.

6.5.3.3 Cache complètement associative (fully-associative cache)


L’algorithme de placement à correspondance directe expliqué dans la section précédente présente
l’avantage d’être très simple à mettre en œuvre et très rapide à l’utilisation. Malheureusement, le
fait que cet algorithme n’offre aucune flexibilité de placement entraîne des remplacements de lignes
qui pourraient être évités, ainsi que des défauts de cache supplémentaires.

Dans une mémoire cache complètement associative (fully-associative cache), un bloc de données
peut être placé dans n’importe quelle ligne de la mémoire cache. La flexibilité est maximale.

0
1
2
3
4
5
6
7
8
9
10
11

Figure 6-12 - Cache complètement associative

La mémoire cache complètement associative est structurée de la manière suivante :

Valide Tag Données (64 octets par ligne)


Oui 1011010011 Mém[1011010011 000000] → Mém[1011010011 111111]
Oui 1011000011 Mém[1011000011 000000] → Mém[1011000011 111111]
Non -
Non -
...
Non -

Page 6.20 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Les mémoires

• Valide – Bit qui indique si la ligne de cache est utilisée ou non.


• Tag – Contient l’adresse complète (10 bits) du bloc présent de la ligne du cache.
• Données – Les 64 octets de données du bloc mémoire transféré en cache.

Dans le cas du placement à correspondance directe, un seul des deux blocs de l’exemple ci-dessus
aurait pu être stocké en mémoire cache, car ils auraient dû occuper tous les deux la ligne 3 (0011).

Lorsque le processeur souhaite accéder au contenu d’une adresse mémoire, le gestionnaire de cache
décompose l’adresse de 16 bits demandée comme suit :

• Bits 15 à 6 = tag (est égal à l’adresse complète du bloc)


• Bits 5 à 0 = index de l’octet au sein de la ligne

Il recherche ensuite s’il existe une ligne de cache valide dont le tag est égal à l’adresse du bloc
accédé. Il n’est pas concevable d’effectuer une recherche séquentielle, car le temps moyen
nécessaire pour trouver une entrée anéantirait le bénéfice d’utiliser une mémoire cache! Une
logique de recherche efficace est complexe à mettre en œuvre et n’est envisageable que pour des
mémoires caches de petite taille.

6.5.3.4 Cache associative par ensemble (set-associative cache)


Cette dernière organisation est un compromis entre les deux précédentes. La mémoire cache est
divisée en plusieurs ensembles de N lignes de cache. L’index de l’ensemble dans lequel un bloc de
données doit se trouver est déterminé au moyen d’une correspondance directe. Par contre, le bloc
peut ensuite être placé dans n’importe laquelle des N lignes de cet ensemble (méthode associative).

La figure suivante illustre ce principe pour une mémoire cache contenant 8 lignes organisées en 4
ensembles de 2 lignes chacun.

0
1
2
0
3
4
1
5
6
2
7
8
3
9
10
11

Figure 6-13 - Cache associative par ensemble

Ainsi, notre mémoire cache de 16 lignes pourrait être divisée en 4 ensembles de 4 lignes (22).

Chaque ensemble est indexé par un nombre de 2 bits qui est obtenu en effectuant le modulo 4 de
l’adresse du bloc, c’est-à-dire en prenant les 2 derniers bits de cette adresse.

© HELMo Campus Guillemins Page 6.21


Les mémoires Architecture des ordinateurs - Théorie

Le tag servant à identifier le bloc stocké dans une ligne de cache est quant à lui constitué des 8 bits
restants de l’adresse du bloc.

La mémoire cache associative par ensemble est structurée de la manière suivante :

Index Valide Tag Données (64 octets par ligne)


ensemble
00 Oui 10110101 Mém[10110101 00 000000] → Mém[10110101 00 111111]
00 Oui 10110100 Mém[10110100 00 000000] → Mém[10110100 00 111111]
00 Non -
00 Non -
01 Non -
01 Non -
01 Non -
01 Non -
...
11 Non -

Pour chacune des 16 lignes de données, la mémoire cache stocke les informations suivantes :

• Valide – Bit qui indique si la ligne de cache est utilisée ou non.


• Tag – Préfixe de 8 bits de l’adresse du bloc qui est effectivement en cache. L’adresse
complète du bloc est obtenue en concaténant ce préfixe avec l’index de l’ensemble.
• Données – Les 64 octets de données du bloc mémoire transféré en cache.

Lorsque le processeur souhaite accéder au contenu d’une adresse mémoire, le gestionnaire de cache
décompose l’adresse de 16 bits demandée comme suit :

• Bits 15 à 8 = tag
• Bits 7 à 6 = index de l’ensemble
• Bits 5 à 0 = index de l’octet au sein de la ligne

La recherche associative du tag est limitée aux 4 lignes de cache de l’ensemble sélectionné.

6.5.3.5 Algorithmes de remplacement


Dans une mémoire cache à correspondance directe, la ligne de cache qui doit être remplacée par un
nouveau bloc est uniquement déterminée à partir de l’adresse du bloc.

Dans une mémoire cache associative, on a le choix entre plusieurs lignes. On privilégiera en premier
lieu les lignes non utilisées. Si toutes les lignes sont utilisées, comment choisir celle qui doit être
remplacée ?

Il existe plusieurs stratégies. Les plus courantes sont :

• choisir une ligne au hasard ;


• utiliser les lignes de manière circulaire (0, 1, 2, …, N-1, 0, 1, …) ;
• utiliser la ligne la moins récemment utilisée.

Page 6.22 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Les mémoires

Cette dernière méthode nécessite de conserver une trace de l’utilisation des différentes lignes. Sa
complexité de mise œuvre augmente avec la taille des ensembles de lignes.

6.5.3.6 Gestion des modifications


Une ligne de cache stocke une copie d’un bloc de données provenant de la mémoire centrale (ou
d’une mémoire cache de niveau supérieur). Si on modifie une donnée dans la mémoire cache sans
modifier la mémoire de niveau supérieur, les deux mémoires ont désormais des contenus différents.

La technique la plus simple pour garantir la cohérence entre les différents niveaux de mémoire
consiste à répercuter immédiatement tout changement dans une mémoire cache vers le niveau de
mémoire supérieur. Cette technique porte le nom d’écriture immédiate (write-through). Elle est très
simple à mettre en œuvre, mais elle est peu efficace puisque chaque accès en écriture à la mémoire
cache nécessite aussi un accès en écriture vers la mémoire centrale. L’accès à la mémoire centrale
étant très lent, il ralentit le fonctionnement du processeur.

Une amélioration possible consiste à utiliser une file d’attente (write buffer) dans laquelle on stocke
les données à écrire en mémoire centrale. La mémoire cache continue à fonctionner à vitesse
maximale, tandis que les données sont écrites au fur et à mesure en mémoire centrale. Bien sûr, si le
rythme des opérations d’écriture dans le cache est trop important, il arrivera un moment où la file
d’attente est pleine. On retombe alors dans le cas précédent : la mémoire cache doit attendre que la
mémoire centrale ait terminé son travail.

Une alternative plus efficace est l’écriture différée (write-back). Dans un premier temps, les données
sont écrites uniquement dans la mémoire cache. Un bit de statut supplémentaire indique si une ligne
de la mémoire cache a été modifiée ou pas. Une ligne de cache modifiée est écrite en bloc dans la
mémoire de niveau supérieur lorsqu’elle doit être remplacée par les données d’un bloc différent. La
technique de l’écriture différée est nettement plus efficace, car elle ne nécessite pas un accès vers la
mémoire centrale pour chaque écriture.

© HELMo Campus Guillemins Page 6.23


Les mémoires Architecture des ordinateurs - Théorie

6.6 Mémoire virtuelle


Le mécanisme de la mémoire virtuelle (virtual memory) sert à satisfaire deux objectifs principaux :

1. Faciliter et sécuriser le partage de la mémoire centrale entre plusieurs programmes.


2. Donner à un programme l’illusion qu’il a accès à une mémoire d’une taille illimitée (ou du
moins nettement plus grande que celle de la mémoire centrale).

6.6.1 Implémentation de base


Le premier objectif est atteint en introduisant deux sortes d’adresses.

• Une adresse physique qui représente une adresse précise en mémoire centrale, c’est-à-dire
une cellule déterminée dans un circuit mémoire.
• Une adresse virtuelle qui désigne quant à elle un emplacement dans un espace d’adressage
logique (virtuel).

Une table de correspondance permet de convertir à la volée une adresse virtuelle vers l’adresse
physique qui lui correspond.

Figure 6-14 - Adresses virtuelles et physiques

[Source du schéma : https://www.irif.fr/~carton/Enseignement/Architecture/Cours/Virtual/principle.pdf]

Lorsqu’un programme utilise un environnement virtualisé, il a l’illusion de disposer de la totalité de


l’espace d’adressage pour lui tout seul. Toutes les références à des données ou à des instructions se
font en utilisant des adresses virtuelles qui sont propres au programme. Ces références sont
indépendantes de l’emplacement réel auquel le programme sera chargé en mémoire centrale lors de
son exécution. C’est le système d’exploitation qui décide de l’emplacement effectif du programme
en mémoire centrale et qui remplit en conséquence la table de correspondance entre les adresses
virtuelles et les adresses physiques.

La sécurité est améliorée du fait qu’un programme n’a pas d’accès direct au contenu de la mémoire
centrale. Il peut uniquement accéder à son espace d’adressage virtuel, c’est-à-dire aux portions de la

Page 6.24 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Les mémoires

mémoire centrale qui lui ont été allouées par le système d’exploitation. Sauf autorisation explicite
(mémoire partagée), un programme ne peut pas accéder aux instructions et données d’un autre
programme.

6.6.2 Implémentation complète


Dès l’instant où on s’est affranchi de la notion d’adresse physique, on peut facilement imaginer une
mémoire virtuelle dont la taille est supérieure à celle de la mémoire physique. Il faudra :

1. Utiliser des adresses virtuelles dont la taille sera supérieure à celle des adresses physiques.
2. Gérer le fait que toutes les données de la mémoire virtuelle ne peuvent pas tenir
simultanément en mémoire centrale.

Nous avons vu comment la mémoire cache permet d’accéder rapidement à des portions de la
mémoire centrale en stockant localement une partie des instructions et des données d’un
programme. De la même manière, on peut imaginer que la mémoire centrale joue à son tour le rôle
de mémoire cache par rapport à la mémoire secondaire (disques magnétiques, SSD, …).

Le contenu complet de la mémoire virtuelle réside sur un périphérique de stockage de masse. Les
portions utilisées par le programme sont copiées en mémoire centrale à la demande, exactement
comme dans le cas d’une mémoire cache. Afin de limiter l’impact des temps d’accès au disque, les
données sont transférées par blocs relativement grands (de l’ordre de 16 Ko) appelés pages.

La figure suivante illustre le principe de fonctionnement d’une mémoire virtuelle de grande capacité.

Mémoire centrale

Page 0
Espace d’adressage Page 3
virtuel du programme Autre progr.
Page 6
Page 0
...
Page 1
Page 4
Page 2
Page 1
Page 3
Table de Autre progr.
Page 4
correspondance ...
Page 5
Page 6 Mémoire de masse
Page 7
...
Page 2
Page 5
Page 7
...

Figure 6-15 - Fonctionnement de la mémoire virtuelle

© HELMo Campus Guillemins Page 6.25


Les mémoires Architecture des ordinateurs - Théorie

Page 6.26 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Les entrées et sorties

77 Les entrées et sorties


7.1 Introduction
L’ordinateur doit être en mesure de communiquer avec le monde extérieur. Nous avons présenté au
chapitre 2 le schéma d’une architecture matérielle type pour un ordinateur.

Bus système

Mémoire Mémoire
CPU
cache centrale

Bus d’entrées/sorties

Disque Imprimante

Périphériques d’entrées/sorties

Figure 7-1 - Architecture type d'un ordinateur

Dans cette architecture, le processeur et les périphériques d’entrées/sorties sont raccordés à un


canal de communication commun, appelé bus d’entrées/sorties.

Supposons que l’on souhaite lire les données stockées sur le secteur 1457 d’un disque dur. Cela
nécessite de réaliser une série de tâches : calculer la localisation du secteur sur le disque (n° de
plateau, n° de piste), déplacer la tête de lecture au bon endroit, lire les données du secteur,
transférer les données vers la mémoire centrale.

Lorsqu’une telle opération d’E/S doit être exécutée par le CPU, comment est-elle réalisée ? En
particulier, quel est le rôle joué par le CPU ? Quelle est la part de ces tâches qui est supervisée
directement par le CPU et celle qui est réalisée de manière autonome par le périphérique d’E/S ?

Le problème principal auquel nous devons faire face est l’extrême lenteur de fonctionnement des
périphériques d’E/S par rapport à la vitesse du CPU. Dans les ordinateurs de première génération, la
gestion des E/S était entièrement réalisée par le CPU et l’électronique de contrôle du périphérique
était réduite au strict minimum. Le CPU établissait une liaison directe avec le périphérique pour lui

© HELMo Campus Guillemins Page 7.1


Les entrées et sorties Architecture des ordinateurs - Théorie

transmettre toutes les instructions nécessaires à la réalisation d’un échange de données. Le CPU
devant travailler au rythme du périphérique, il passait un temps considérable à attendre !

Afin d’utiliser le CPU de manière plus rationnelle, l’idée est de permettre à chaque périphérique de
réaliser de manière autonome des tâches plus ou moins complexes et de mettre en place un système
de signalisation qui indique au CPU quand la tâche est terminée, ou quand le périphérique nécessite
une intervention du CPU.

Deux systèmes ont été envisagés pour permettre à un périphérique de signaler au CPU qu’il est prêt
à réaliser une opération d’E/S, ou lorsqu’il a terminé l’opération demandée par le CPU :

• Les drapeaux (flags) – Le périphérique signale qu’il est prêt en positionnant un drapeau (bit)
dans un registre de statut. Le processeur passe régulièrement en revue les drapeaux de tous
les périphériques afin de déterminer ceux qui sont disponibles ou dont il doit s’occuper.
Cette technique n’est pas très efficace, car le CPU doit surveiller en permanence tous les
drapeaux.
• Les interruptions (interrupts) – Le périphérique envoie un signal, appelé interruption, au CPU
pour signaler qu’il est prêt. Le processeur interrompt l’exécution du programme en cours et
exécute un programme de gestion spécial qui réalise l’opération d’E/S (cf. section 5.7
« Exceptions et interruptions »). L’approche par interruptions est la plus répandue.

L’importance des tâches qu’un périphérique d’E/S est à même de réaliser de manière autonome sans
intervention du CPU dépend de :

• l’intelligence du contrôleur du périphérique (électronique plus ou moins complexe) ;


• la possibilité d’accéder directement à la mémoire centrale sans intervention du CPU (DMA –
Direct Memory Access);
• l’existence d’un ou plusieurs processeurs spécialisés pour gérer les E/S (canal d’E/S).

7.2 Interruptions hiérarchisées


La gestion des interruptions a été décrite dans la section 5.7 «Exceptions et interruptions».

Que se passe-t-il lorsque plusieurs périphériques d’E/S envoient simultanément des interruptions au
CPU ? Ou bien lorsqu’une interruption est reçue alors que le traitement de la précédente n’est pas
encore terminé ?

Les ordinateurs modernes mettent en place un système d’interruptions hiérarchisées. Dans un tel
système, une priorité est attribuée à chaque interruption.

• Des interruptions de même priorité sont traitées dans leur ordre d’arrivée.
• Le programme de traitement d’une interruption peut lui-même être interrompu par une
interruption de priorité supérieure.
• Lorsque le traitement d’une interruption est terminé, le contrôle du CPU est attribué au
programme en attente qui a la priorité la plus élevée.

Page 7.2 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Les entrées et sorties

On obtient ainsi une cascade d’appels imbriqués des sous-programmes de gestion d’interruptions.
Les contextes d’exécution étant généralement sauvegardés sur une pile.

Les systèmes de gestion d’interruptions peuvent être très sophistiqués. Parfois, ils jouent même un
rôle critique. C’est par exemple le cas dans les applications en temps réel (acquisition de mesures,
contrôle de processus industriels…) où il est indispensable de réagir à une interruption dans un laps
de temps maximum imposé.

7.3 Contrôleur de périphérique


Un contrôleur de périphérique est un circuit électronique spécialisé qui permet de raccorder un
équipement d’E/S à l’ordinateur.

Il existe une très grande variété de périphériques d’entrées/sorties possédant des caractéristiques
très différentes : type d’accès, vitesse de transfert, taille des données, connectique, commandes de
contrôle, etc. Afin de faire face à une telle diversité, l’ordinateur impose une interface standardisée
pour communiquer avec les périphériques d’E/S.

Le rôle premier du contrôleur est de réaliser la conversion entre l’interface propriétaire du


périphérique et l’interface standardisée de l’ordinateur auquel il est connecté.

Les contrôleurs modernes sont de plus en plus sophistiqués. Ce sont des processeurs à part entière
qui ajoutent de nombreuses fonctionnalités supplémentaires : gestion d’une mémoire cache,
détection d’erreurs, cryptage et décryptage à la volée, etc.

7.4 Accès direct à la mémoire (DMA)


Comme son nom l’indique, le DMA (Direct Memory Access) est un dispositif qui permet à un
périphérique d’échanger directement des données avec la mémoire centrale sans faire appel au CPU.

Bus système

CPU Mémoire

Bus d’entrées/sorties

Contrôleur Contrôleur
périphériques périphériques DMA

Contrôleur
périphériques

Figure 7-2 - Accès direct à la mémoire

© HELMo Campus Guillemins Page 7.3


Les entrées et sorties Architecture des ordinateurs - Théorie

Le CPU démarre l’opération d’E/S en fournissant au contrôleur DMA toutes les informations
nécessaires : périphérique concerné, type d’opération (lecture/écriture), quantité de données à
transférer, adresse de début en mémoire centrale. Le DMA réalise le transfert de données de
manière autonome et signale la fin de l’opération en envoyant une interruption au CPU.

Comme il n’est généralement pas possible d’effectuer deux accès simultanés à la mémoire centrale,
il arrive que le CPU et le DMA entrent en conflit. Il faut donc prévoir un mécanisme de gestion des
priorités d’accès à la mémoire.

Généralement, le DMA est prioritaire sur le CPU. Lorsqu’il doit effectuer un transfert de données, le
DMA obtient un accès exclusif à la mémoire pendant toute la durée de ce transfert. Le CPU est alors
mis en attente. On appelle cette technique le vol de cycles, car le DMA vole des cycles d’accès à la
mémoire au CPU. Le fonctionnement d’un périphérique d’E/S étant nettement plus lent que celui du
CPU, le DMA n’est heureusement pas capable de monopoliser l’accès à la mémoire en permanence.

Pour limiter les conflits d’accès et garantir au CPU un accès performant à la mémoire, on peut prévoir
un bus d’E/S séparé du bus système et utiliser une mémoire à double accès (cf. Figure 7-2).

7.5 Canaux d’entrées/sorties


Un canal d’entrées/sorties est un processeur spécialisé programmable.

Contrairement au DMA qui réalise uniquement des transferts de données, un canal est capable
d’exécuter de véritables programmes d’entrées/sorties et d’enchaîner plusieurs opérations
successives. Le CPU intervient uniquement pour démarrer le programme de canal adéquat et lui
fournir les paramètres nécessaires.

Un canal d’E/S peut être dédié à un seul périphérique (canal sélecteur) ou partagé entre plusieurs
périphériques à faible débit (canal multiplexé).

Un canal d’E/S peut être connecté directement au(x) périphérique(s) qu’il contrôle, ou y accéder par
l’intermédiaire d’un bus d’E/S.

CPU Mémoire

Bus système

Canal E/S Canal E/S

Bus d’entrées/sorties
Contrôleur
périphériques

Contrôleur Contrôleur
périphériques périphériques

Figure 7-3 - Les canaux d'entrées/sorties

Page 7.4 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Les entrées et sorties

7.6 Bus de communication


7.6.1 Généralités
Un bus est un moyen de communication qui relie plusieurs composants ou équipements pour leur
permettre d’échanger des informations. Il est composé d’un canal de communication physique
(ensemble de pistes sur un circuit imprimé ou de fils) et d’un contrôleur qui supervise les transferts
de données et gère les accès au bus afin d’empêcher les conflits éventuels.

Un bus interne interconnecte différents composants au sein d’un ordinateur. Un bus externe permet
de connecter des périphériques à un ordinateur, ou de connecter plusieurs ordinateurs entre eux.

Parmi les bus internes, on distinguera généralement :

• Le bus système qui connecte le CPU à la mémoire centrale à très grande vitesse.

• Le bus d’entrées/sorties, également appelé bus d’extension, qui permet de connecter des
périphériques d’E/S ou des cartes d’extension.

La transmission des informations sur un bus peut être synchrone (cadencée par une horloge) ou
asynchrone (transfert initié à la demande du CPU ou d’un contrôleur d’E/S).

Les données peuvent être transmises sur le bus un seul bit à la fois (bus série) ou plusieurs bits à la
fois (bus parallèle).

Enfin, des bus de différents types peuvent être interconnectés en utilisant un élément intermédiaire
appelé pont.

7.6.2 Les bus d’extension


Les 2 principaux bus d’extension utilisés actuellement sont :

• PCI (Peripheral Component Interconnect) – Bus parallèle de 32 (ou 64) bits partagé entre tous
les périphériques connectés. Il permet un débit théorique de 133 Mo/s (ou 266 Mo/s).

• PCI Express (PCIe) – Bus série qui transporte les données par paquets. Il offre un débit qui
varie entre 250 Mo/s et 64 Go/s suivant les versions. Au sens strict du terme, PCI Express
n’est pas un bus, il s’agit en fait d’un ensemble de liaisons (links) point à point, qui
connectent les périphériques à un nœud central (root complex). La transmission des
informations s’effectue en série (1 bit à la fois) sur des lignes (lines) bidirectionnelles qui
offrent un débit de 250 Mo/s à 2 Go/s dans chaque sens. En fonction du débit nécessaire au
périphérique, une liaison peut utiliser 1, 2, 4, 16 ou 32 lignes.

Dans la figure ci-après, on voit que la norme PCI Express est conçue pour pouvoir fonctionner avec
l’ancienne norme PCI. Un pont (PCI Bridge) réalise l’adaptation entre le bus PCI et le monde PCIe.

© HELMo Campus Guillemins Page 7.5


Les entrées et sorties Architecture des ordinateurs - Théorie

CPU Mémoire

Composant racine (root complex)

Périphérique
Switch PCI Bridge
Périphérique PCIe
PCIe

Bus PCI
Périphérique
Périphérique PCIe
PCIe

Périphérique Périphérique
PCI PCI

Figure 7-4 - Exemple d'architecture PCI Express

7.6.3 Les bus externes


A la base, la norme PCI Express n’est pas conçue pour connecter directement des périphériques
externes à l’ordinateur. Elle sert à interconnecter les composants présents sur la carte mère de
l’ordinateur, ou à connecter des cartes d’extension à la carte mère.

Un périphérique externe (disque dur, souris, webcam) est raccordé à l’ordinateur au moyen d’un bus
spécifique, appelé bus externe. Le contrôleur de ce bus externe est un circuit présent sur la carte
mère de l’ordinateur, ou c’est une fonctionnalité ajoutée au moyen d’une carte d’extension.

Les principaux bus externes utilisés actuellement sont : eSATA, SCSI, FireWire (IEEE 1394), USB,
ThunderBolt, Fibre Channel, InfiniBand.

Nous renvoyons le lecteur aux ouvrages de référence pour obtenir des informations détaillées sur ces
différentes technologies.

Page 7.6 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Les entrées et sorties

7.7 Les réseaux


7.7.1 Avant-propos
Le contenu de cette section est basé sur celui de la section 11.6 du livre « Architecture et technologie
des ordinateurs, P. Zanella, Y. Ligier, E. Lazard, 5e édition, éditions Dunod ».

L’objectif de cette section n’est pas d’expliquer en détail le fonctionnement des différents types de
réseaux informatiques, mais uniquement d’introduire brièvement quelques notions de base, ainsi
que les éléments de vocabulaire correspondants.

7.7.2 Étendue d’un réseau


Un réseau informatique peut être vu comme la prolongation naturelle d’un bus externe. Il permet à
des équipements (nœuds du réseau) de communiquer au-delà de l’environnement immédiat de
l’ordinateur.

On peut classer les réseaux en fonction de leur étendue.

• Réseau personnel – PAN (Personal Area Network) : réseau dont les nœuds se trouvent dans
un voisinage immédiat de quelques mètres (clavier, souris, scanner, imprimante…). Un PAN
interconnecte les équipements au moyen d’un bus externe (ex. USB) ou d’une technologie
sans fil (BlueTooth, WiFi, …). Dans ce dernier cas, on parle de WPAN (Wireless PAN).
• Réseau local – LAN (Local Area Network) : réseau dont les nœuds se trouvent dans le même
bâtiment ou dans des bâtiments voisins. La distance couverte est de quelques dizaines ou
centaines de mètres. Un réseau local utilise généralement la technologie Ethernet (fils de
cuivre ou câble coaxial), ou une transmission sans fil de type WiFi. Dans ce dernier cas, on
parle de WLAN (Wireless LAN).
• Réseau métropolitain – MAN (Metropolitan Area Network) : réseau dont les nœuds se
trouvent dans une même métropole. La distance couverte est de quelques kilomètres à une
dizaine de kilomètres au plus. Le support de transmission est généralement la fibre optique.
• Réseau étendu – WAN (Wide Area Network) : réseau dont les nœuds sont
géographiquement très éloignés, de quelques centaines à quelques milliers de kilomètres.
Internet est un WAN à l’échelle de la planète.

7.7.3 Méthodes de diffusion des données


Le plus souvent, la transmission d’informations sur un réseau s’effectue uniquement entre deux
utilisateurs. On parle alors de transmission point à point (unicast). Chaque utilisateur connecté au
réseau est identifié par une adresse. L’expéditeur et le destinataire d’un message ne sont pas
nécessairement directement connectés. Dans ce cas, l’adresse du destinataire est ajoutée au
message et celui-ci est transmis de proche en proche jusqu’à atteindre sa destination finale. C’est un
peu le même principe que dans un service postal classique.

© HELMo Campus Guillemins Page 7.7


Les entrées et sorties Architecture des ordinateurs - Théorie

Si on désire envoyer le même message à de nombreux utilisateurs, on peut bien sûr l’envoyer
individuellement à chaque utilisateur, mais il est plus efficace de l’envoyer simultanément :

• à tous les utilisateurs, on parle alors de diffusion (broadcast), c’est le même principe que
celui utilisé pour la radiodiffusion ;
• à un groupe limité d’utilisateurs, on parle alors de multidiffusion (multicast), c’est le mode
de transmission généralement utilisé pour la vidéoconférence entre les membres d'un même
groupe.

7.7.4 Techniques de commutation de données


Pour transiter de l’expéditeur au destinataire, les données empruntent un chemin qui passe par un
certain nombre de nœuds intermédiaires. Différentes techniques sont utilisées pour réaliser
l’acheminement du message au sein du réseau.

• Commutation de circuits (circuit switching) : on établit une connexion physique temporaire


entre le nœud d’origine et celui de destination. La transmission démarre lorsque la
connexion est établie. La connexion reste établie tant que la communication n’est pas
explicitement clôturée, même si aucune donnée n’est transmise. C’est le principe de
fonctionnement historique du réseau téléphonique.
• Commutation de messages (message switching) : le message est acheminé de proche en
proche dans le réseau sur base de l’adresse du destinataire. Chaque nœud intermédiaire
reçoit et stocke le message complet, avant de le retransmettre vers le nœud suivant. On
n’établit pas une connexion de bout en bout. Le message emprunte une succession de
connexions point à point. Ce système présente quelques inconvénients. Ainsi, chaque nœud
doit disposer des ressources nécessaires pour stocker la totalité du message. D’autre part, la
probabilité d’une erreur de transmission augmente avec la taille du message. En cas d’erreur,
le message doit être retransmis dans sa totalité.
• Commutation de paquets (packet switching) : le principe est similaire à celui de la
commutation de messages, si ce n’est que la taille maximale d’un message est limitée. On
parle alors d’un paquet. Lorsque le message original dépasse la taille maximale, il est
découpé en plusieurs paquets qui sont numérotés. Chaque paquet est transmis
individuellement. La taille d’un paquet étant réduite, les nœuds intermédiaires ont besoin de
moins de ressources de stockage. La probabilité d'une erreur de transmission pour un paquet
est plus faible que pour le message complet. Seul le paquet erroné doit être retransmis. Le
destinataire reconstitue le message initial en assemblant les différents paquets sur base de
leurs numéros.

Page 7.8 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Les entrées et sorties

7.7.5 Topologie des réseaux


La topologie d’un réseau indique la manière dont les nœuds du réseau sont interconnectés. On
distingue les topologies principales suivantes.

• Réseau maillé – Deux nœuds quelconques peuvent être reliés


directement. On dit que le réseau est complètement maillé si chaque
nœud est connecté à tous les autres, ce qui n’est pas envisageable
avec un grand nombre de nœuds. Généralement, le réseau est
partiellement maillé. Plus le maillage est dense et meilleure est la
redondance du réseau en cas de panne d’un nœud ou d’une connexion.

• Réseau en étoile – Tous les nœuds du réseau sont connectés à un nœud


central. Cet élément central supporte toute la charge du réseau et
constitue un maillon faible.

• Réseau en arbre – Les nœuds du réseau sont répartis sur plusieurs niveaux
hiérarchiques. Les nœuds d’un même niveau n’ont pas de connexion
directe. Ils communiquent entre eux par l’intermédiaire d’un nœud de
niveau supérieur.

• Réseau en boucle – Chaque nœud du réseau dispose d’une connexion


point à point vers 2 autres nœuds, l’ensemble constituant une boucle.

• Réseau en bus – Tous les nœuds du réseau sont connectés au même


support physique qui utilise une technique de diffusion (broadcast).

Un réseau réel sera généralement constitué d’une combinaison de ces différentes topologies.

© HELMo Campus Guillemins Page 7.9


Les entrées et sorties Architecture des ordinateurs - Théorie

Page 7.10 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Le système d’exploitation

88 Le système d’exploitation
8.1 Introduction
Jusqu’à présent, nous nous sommes beaucoup intéressés à l’ordinateur du point de vue de son
architecture matérielle :

• Niveau 0 – Électronique digitale


• Niveau 1 – Microarchitecture
• Niveau 2 – Jeu d’instructions

En pratique, ce qui fait l’utilité d’un ordinateur, ce sont surtout les logiciels qu’il est capable
d’exécuter. Ce sont eux qui tirent parti de la véritable puissance de l’outil informatique.

Le système d’exploitation (Operating System – OS) est le maillon indispensable situé entre les
couches matérielles (partie système) et les couches logicielles (partie utilisateur) de l’ordinateur.

Le rôle principal du système d’exploitation est, comme son nom l’indique, de permettre l’exploitation
de l’ordinateur. A ce titre, le système d’exploitation :

• Assure la gestion des ressources matérielles de l’ordinateur, telles que le CPU ou la mémoire.
• Organise l’exécution des programmes.
• Prend en charge la gestion des périphériques d’entrées/sorties.
• Assure la gestion des exceptions et des interruptions.
• Organise le stockage des informations sur les dispositifs de stockage (systèmes de fichiers).
• Fournit à l’utilisateur un ensemble d’instructions supplémentaires et de sous-programmes
(system calls) qui ajoutent des fonctionnalités de plus haut-niveau et qui lui facilitent la vie.
• Facilite l’interaction de l’utilisateur avec la machine au moyen d’une interface de commande
par ligne et/ou d’une interface graphique.
• Contient un ensemble de logiciels utilitaires qui aident à la maintenance du système
(formatage des disques), au développement d’applications (assembleur, compilateur,
débogueurs, …), à la communication avec d’autres ordinateurs (ftp, telnet, …), etc.

Avec le temps, les tâches assurées par le système d’exploitation se sont diversifiées. Un système
d’exploitation moderne propose un ensemble de programmes toujours plus vaste dont la finalité
s’écarte de plus en plus de son rôle initial. Ainsi, les systèmes d’exploitation Linux, MacOS ou
Windows sont constitués de dizaines de logiciels utilitaires et applicatifs qui offrent des
fonctionnalités qui vont bien au-delà de la simple exploitation des ressources matérielles de
l’ordinateur.

© HELMo Campus Guillemins Page 8.1


Le système d’exploitation Architecture des ordinateurs - Théorie

8.2 Le noyau
Au cœur de tout système d’exploitation se trouve le noyau (kernel). Le noyau est la portion du
système d’exploitation qui se charge de l’interface entre le logiciel et le matériel au niveau le plus
bas.

Le noyau s’occupe de :

• L’allocation du (ou des) CPU(s) aux différents processus.


• La gestion des exceptions et des interruptions.
• L’accès de bas-niveau à la mémoire centrale.
• L’accès de bas-niveau aux périphériques d’E/S.

Ces tâches sont à la base du fonctionnement même de l’ordinateur. Elles sont exécutées en
permanence et nécessitent donc une efficacité maximale.

Pour cette raison, le noyau est la seule portion du système d’exploitation qui doit résider en
permanence en mémoire centrale. Le noyau est généralement codé directement en assembleur pour
garantir que son exécution soit la plus rapide possible.

8.3 Systèmes multitâches


Les ordinateurs modernes sont tous des systèmes dits multiprogrammés. C’est-à-dire des systèmes
dans lesquels plusieurs programmes sont présents simultanément en mémoire centrale.
Généralement, le système d’exploitation permet d’exécuter plusieurs programmes simultanément,
on parle alors d’un système d’exploitation multitâches.

Un système multitâche est envisageable même si l’ordinateur ne dispose que d’un seul processeur.
En fait, que l’ordinateur contienne un processeur ou plusieurs ne change pas grand-chose. Dans la
plupart des cas, le nombre de tâches à exécuter sera de toute façon supérieur aux nombres de
processeurs disponibles. La simultanéité d’exécution apparente de toutes ces tâches est obtenue par
le fait que chaque processeur alloue une partie de son temps en alternance aux différents
programmes qu’il doit exécuter. L’alternance rapide entre les tâches donne l’impression d’une
exécution simultanée.

On appelle processus l’exécution d’un programme (ensemble d’instructions) par un processeur.

Différentes techniques ont été utilisées pour permettre l’exécution simultanée de plusieurs
programmes par un ordinateur :

• La multiprogrammation (multiprogramming) consistait initialement à allouer le CPU à


l’exécution d’un autre programme dès l’instant où le programme en cours d’exécution
réalisait une opération d’entrée/sortie. On utilisait utilement le CPU plutôt que d’attendre la
fin de l’opération d’E/S sans rien faire. Il n’y avait aucune garantie de partage équitable du
CPU entre les différents programmes. Ainsi, un programme qui ne réalisait pas d’opérations
d’E/S pouvait monopoliser le CPU très longtemps.

Page 8.2 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Le système d’exploitation

• Le multitâche coopératif (nonpreemptive multitasking) est une première évolution vers un


partage du temps (time-sharing) plus équitable entre les différents programmes. Plutôt que
d’attendre une hypothétique opération d’entrée/sortie, chaque programme est conçu de
manière à rendre périodiquement la main au système d’exploitation et permettre ainsi à
d’autres programmes de s’exécuter.
Inconvénients :
o Le système d’exploitation n’a pas de contrôle sur ce qui se passe et ne peut donc pas
optimiser l’allocation du CPU en fonction de l’utilisation des ressources matérielles.
o Il faut que tous les programmes coopèrent de manière équitable.
o Un bug (ex. boucle infinie) peut bloquer le système entier.

• Le multitâche préemptif (preemptive multitasking) permet de garantir une répartition


équitable des ressources du CPU entre les différents processus. C’est le système
d’exploitation qui gère l’allocation du CPU entre les différents processus. Le passage d’un
processus à un autre s’effectue :
o Sur la base d’événements systèmes qui placent naturellement un processus dans un
état d’attente (ex. opération d’E/S) ;
o Sur la base d’une durée d’exécution maximale, de manière à garantir un juste
partage du CPU entre tous les processus ;
o Sur la base de la priorité attribuée à chaque processus.

Le système d’exploitation comporte, un processus appelé planificateur (scheduler) qui réalise


l’ordonnancement des tâches prêtes à utiliser le CPU en fonction de leurs priorités et de la
disponibilité des ressources matérielles utilisées. Ces tâches sont placées dans une file d’attente.

Un second processus appelé allocateur (dispatcher) est chargé de répartir le temps du CPU entre les
différents processus de la file d’attente.

Lorsque le processeur passe d’un processus à un autre, on dit qu’il effectue un changement de
contexte (context switching). Il faut sauvegarder l’état d’exécution du processus interrompu, c’est-à-
dire son contexte, afin de pouvoir poursuivre son exécution ultérieurement. Le contexte d’un
processus contient notamment les valeurs stockées dans les registres du processeur.

C’est l’allocateur qui se charge de sauvegarder le contexte du processus interrompu et de rétablir le


contexte d’exécution correct du processus suivant.

© HELMo Campus Guillemins Page 8.3


Le système d’exploitation Architecture des ordinateurs - Théorie

8.4 Gestion de la mémoire


Lorsqu’un seul programme à la fois peut se trouver en mémoire centrale, la mémoire est utilisée
uniquement par le système d’exploitation et le programme à exécuter. Généralement, le système
d’exploitation utilise la mémoire basse, c’est-à-dire qu’il démarre à l’adresse 0. Le programme utilise
la mémoire haute, située au-delà de la partie occupée par l’OS.

Dans un système multiprogrammé, la situation se complique :

• Plusieurs programmes doivent pouvoir coexister en mémoire.


• La taille de chaque programme est variable et peut varier en cours d’exécution.
• Un programme ne doit pas empiéter sur la mémoire allouée à un autre programme.

Plusieurs techniques sont utilisées :

1. La mémoire est divisée en partitions fixes, c’est-à-dire en zones de mémoire dont


l’emplacement et la taille sont définis à l’avance par le système d’exploitation. Toutes les
partitions n’ont pas nécessairement la même taille, ce qui permet de traiter des programmes
petits et grands. Néanmoins, la taille maximale d’un programme est limitée par le nombre de
partitions définies. Par ailleurs, un programme ne peut être chargé en mémoire que si une
partition suffisamment grande est disponible et il n’occupera généralement pas la totalité de
l’espace mémoire qui lui est alloué. Ce système de gestion de la mémoire est donc peu
efficace et entraîne un gaspillage important de la mémoire centrale.

2. La mémoire est divisée en partitions de tailles variables. La taille d’une partition correspond
exactement à la quantité de mémoire demandée par un programme. Les inconvénients de ce
système sont :
• La taille d’une partition est fixée une fois pour toutes lors du chargement du
programme. Si celui-ci ne connaît pas exactement à l’avance la quantité de données
qu’il va devoir traiter, il aura tendance à réserver plus de mémoire que nécessaire, ce
qui entraîne à nouveau du gaspillage.
• Une partition occupe une zone mémoire d’un seul tenant. Au fur et à mesure de
l’exécution des programmes, la mémoire libre va avoir tendance à se fragmenter et il
devient de plus en plus difficile de trouver la place nécessaire pour stocker une
partition. Il faut régulièrement compacter la mémoire, c’est-à-dire déplacer les
partitions en mémoire pour regrouper les zones utilisées et recréer de grandes zones
libres continues.

Le déplacement du programme en mémoire (réallocation) entraîne une modification des


adresses référencées par le programme. Pour que cette technique fonctionne de manière
efficace, le programme doit utiliser un mode d’adressage relatif (ou indexé) : un registre
prédéfini contient l’adresse de début du programme en mémoire et toutes les adresses
référencées par le programme (instructions ou données) sont calculées relativement à cette
adresse de base. Lorsque le programme est déplacé en mémoire, il suffit de modifier
l’adresse de base dans le registre.

Page 8.4 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Le système d’exploitation

3. Pour s’affranchir de la contrainte de devoir allouer une zone mémoire d’un seul tenant à un
programme, l’étape suivante consiste à diviser un programme en segments, c’est-à-dire en
portions plus ou moins petites qui contiennent seulement une partie des instructions ou des
données. Fondamentalement, chaque segment est géré comme une partition de taille
variable. La taille plus réduite des segments fait que la fragmentation de la mémoire est
moins problématique et diminue la fréquence des réallocations. De plus, un programme peut
allouer/libérer dynamiquement des segments durant son exécution, ce qui lui permet
d’utiliser la mémoire plus efficacement pour stocker ses données. Le système d’exploitation
maintient la liste des segments utilisés par chaque programme.

Dans les 3 méthodes exposées ci-dessus, une question se pose : comment empêcher un programme
d’aller lire, ou pire, d’aller modifier la zone mémoire allouée à un autre programme ou celle utilisée
par le système d’exploitation ?

La protection de la mémoire s’effectue comme suit :

• Chaque programme utilise le mode d’adressage relatif. Il n’utilise pas des adresses
mémoires absolues, mais calcule toute adresse effective relativement au contenu d’un
registre de base.
• Le registre de base contient l’adresse de début de la partition (ou du segment) en mémoire.
• Un deuxième registre, appelé registre de borne, contient quant à lui l’adresse supérieure de
la partition (ou du segment).
• Seul le système d’exploitation est autorisé à modifier le contenu des registres de base et de
borne lors de l’activation d’un processus.
• Lorsqu’un programme s’exécute, un dispositif du processeur vérifie que toute adresse
référencée par le programme appartient bien à la zone mémoire allouée au processus. Si ce
n’est pas le cas, une exception est générée afin d’alerter le système d’exploitation.

L’étape suivante en termes de flexibilité d’allocation de la mémoire et de transparence du point de


vue du programme, c’est l’utilisation de la mémoire virtuelle, dont nous avons parlé au chapitre 6.
Elle repose sur deux notions que nous rappelons :

• La séparation complète entre les adresses utilisées par un programme (adresses virtuelles
dans un espace d’adressage fictif propre au programme) et les adresses physiques qui seront
utilisées une fois qu’il sera chargé en mémoire centrale.
• Le découpage de la mémoire centrale en pages (blocs de mémoire) et son utilisation comme
mémoire cache d’une mémoire virtuelle stockée en mémoire secondaire (disque dur, SSD).

© HELMo Campus Guillemins Page 8.5


Le système d’exploitation Architecture des ordinateurs - Théorie

8.5 Processus et threads


Un thread, ou fil (d’exécution), ou encore processus léger (lightweight process) correspond, tout
comme un processus classique, à l’exécution d’un programme par le processeur.

La différence provient du fait qu’un thread n’est pas un programme isolé, mais bien un sous-
processus dérivé d’un processus parent, parfois appelé processus poids lourd (heavyweight process).
Un thread utilise le code de son processus parent. Il partage également l’espace d’adressage de son
processus parent et peut donc facilement partager des données avec celui-ci ou avec d’autres
threads. Par contre, chaque thread est exécuté indépendamment de son parent, il possède son
propre contexte d’exécution et éventuellement ses propres données.

Exemples d’utilisation des threads :

• La gestion d’une interface graphique dans laquelle la gestion de chaque fenêtre est réalisée
par un thread différent.
• Un serveur Web dans lequel chaque requête HTTP est traitée par un thread séparé.

Avantages :

• L’échange de données entre différents threads est très efficace puisqu’ils partagent le même
espace d’adressage.
• Pas de duplication du code en mémoire : les threads partagent le même code.
• Changement de contextes plus rapides, car même mémoire virtuelle.

Inconvénients :

• Programmes plus complexes à mettre en œuvre.


• Le partage des données entre plusieurs threads nécessite de prendre des précautions pour
ne pas arriver à des situations incohérentes (synchronisation, risque d’inter-blocage…)

Page 8.6 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Les architectures à processeurs multiples

9 Les architectures à
9 processeurs multiples

9.1 Introduction
L’augmentation de la puissance de calcul des ordinateurs durant ces 50 dernières années a été
phénoménale. Cette puissance accrue nous permet de résoudre aujourd’hui des problèmes
extrêmement complexes au moyen d’un ordinateur, alors que ce n’était même pas imaginable il y a
seulement quelques dizaines d’années.

Face à ces nouveaux moyens toujours plus performants, l’imagination de l’homme est sans limites.
De nouvelles idées d’utilisation de l’outil informatique voient constamment le jour, toujours plus
gourmandes en puissance de calcul : décodage du génome humain, simulations numériques de plus
en plus sophistiquées…

Jusqu’à présent, l’amélioration des technologies existantes permettait d’assurer une augmentation
régulière des performances : intégration plus poussée, vitesse d’horloge plus rapide, processeur plus
efficace, mémoire cache et mémoire centrale plus grandes, etc.

Malheureusement, nous avons vu dans notre introduction au chapitre 1 que l’intégration de plus en
plus poussée se heurte aux limites physiques de la technologie actuelle (semi-conducteurs à base de
silicium). Sauf changement radical de la technologie utilisée, il n’est plus possible d’augmenter de
façon significative la puissance de calcul d’un processeur unique.

L’industrie de l’informatique se tourne donc de plus en plus vers le parallélisme, c’est-à-dire la


capacité à effectuer plusieurs tâches simultanément.

Une autre voie complémentaire est celle des processeurs spécialisés. Un processeur spécialisé est
conçu pour réaliser un type de tâches bien défini : cryptage de données, compression de données,
traitements multimédias, processeur réseau… Il est alors possible d’optimiser spécifiquement son
architecture en fonction des tâches à réaliser, ce qui n’est pas le cas pour un processeur généraliste.

© HELMo Campus Guillemins Page 9.1


Les architectures à processeurs multiples Architecture des ordinateurs - Théorie

9.2 Différentes formes de parallélisme


Le parallélisme peut revêtir plusieurs formes et servir des objectifs très divers.

Sur le plan matériel, on distinguera le parallélisme interne qui consiste à exécuter plusieurs tâches
simultanément au sein d’un seul processeur et le parallélisme externe dans lequel plusieurs
processeurs se répartissent les tâches en collaborant de manière plus ou moins étroite.

Nous avons évoqué au chapitre 5 différentes techniques de parallélisme interne : le pipelining, le


traitement vectoriel, les architectures super scalaires. On peut également ajouter le multitâche qui
donne l’apparence d’une exécution simultanée de plusieurs tâches par le partage du temps du CPU
entre plusieurs processus.

Le parallélisme externe peut lui aussi prendre différentes formes :

• Processeurs à cœurs (core) multiples. Chaque cœur est un processeur à part entière. Le fait
de les regrouper au sein d’un même circuit intégré permet une communication très rapide
entre les différents processeurs, ainsi que l’utilisation d’une mémoire cache partagée. Cette
approche permet à plusieurs cœurs de collaborer de manière très efficace à l’exécution
d’une tâche commune.
• Plusieurs processeurs dans un seul ordinateur (partage de la mémoire centrale uniquement).
• Plusieurs ordinateurs interconnectés par un réseau très rapide : grappe de serveurs (cluster),
grille informatique (grid computing).

Du point de vue de l’utilisateur, on distinguera le parallélisme transparent et le parallélisme


explicite.

Dans le cas du parallélisme transparent, l’utilisateur n’a pas à se préoccuper de la manière dont les
tâches sont exécutées en parallèle : le système d’exploitation organise l’exécution simultanée de
plusieurs processus, le compilateur optimise le code du programme pour tirer parti des spécificités
du processeur (par exemple utiliser plusieurs unités de calcul simultanément), le processeur
maximise l’exécution du programme grâce au pipelining et à la mémoire cache.

Le parallélisme explicite demande quant à lui que l’utilisateur conçoive son programme de manière
spécifique :

• décomposer le programme en sous-tâches susceptibles d’être exécutées simultanément,


• utiliser les instructions spécifiques d’un processeur vectoriel,
• concevoir des algorithmes parallèles,
• organiser les données par petits morceaux et les traiter simultanément,
• etc.

Le parallélisme explicite demande une approche radicalement différente dans la conception des
programmes, des algorithmes et des structures de données. C’est probablement le domaine de
l’informatique où il reste la plus grosse marge de manœuvre en termes d’amélioration des
performances.

Page 9.2 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Les architectures à processeurs multiples

9.3 Classification des systèmes parallèles


De très nombreuses architectures d’ordinateurs (ou systèmes) parallèles ont été conçues. Afin d’y
mettre un peu d’ordre, une classification a été proposée en 1966 par Michael J. Flynn, professeur à
l’université de Stanford.

Cette classification répartit les architectures en fonction du nombre de flux d’instructions et du


nombre de flux de données.

Une instruction Plusieurs instructions


Un flux de données SISD MISD
Plusieurs flux de données SIMD MIMD
Figure 9-1 - Classification de Flynn de architectures parallèles

• SISD (Single Instruction, Single Data stream) – C’est l’ordinateur classique, basé sur
l’architecture de Von Neumann. Il exécute une seule instruction à la fois (une seule unité de
contrôle) et produit un seul résultat à la fois (une seule unité arithmétique et logique). Le
seul parallélisme éventuel est interne, par exemple grâce à l’utilisation d’un pipeline.

• SIMD (Single Instruction, Multiple Data streams) – L’unité de contrôle va chercher les
instructions du programme une à la fois, mais elle dispose de plusieurs unités de calcul ce qui
lui permet d’exécuter plusieurs instructions en parallèle par recouvrement des cycles
d’exécution des instructions successives. Elle peut aussi exécuter la même instruction sur
plusieurs données simultanément. Les architectures super scalaires et vectorielles sont du
type SIMD. Les extensions MMX, SSE et AVX des processeurs Intel offrent également un
parallélisme de type SIMD.

• MISD (Multiple Instructions, Single Data stream) – Une telle architecture aurait pour
caractéristique d’appliquer simultanément plusieurs instructions à une même donnée. Il n’y
a pas d’exemple connu d’ordinateur basé sur cette architecture.

• MIMD (Multiple Instructions, Multiple Data streams) – Cette dernière catégorie contient
toutes les architectures composées de plusieurs processeurs travaillant de concert au sein
d’un système global.

La catégorie MIMD est relativement vaste. On distinguera au sein de cette catégorie les systèmes :

• multicœurs ou multiprocesseurs qui sont caractérisés par un niveau de couplage élevé. Les
différents processeurs sont connectés à un bus commun et ils partagent de la mémoire
centrale, voire même de la mémoire cache pour les systèmes multicœurs (mémoire
partagée).

• Multiordinateurs qui sont caractérisés par un couplage faible. Les différents ordinateurs
possèdent leur propre mémoire (mémoire distribuée). Ils sont interconnectés au moyen d’un
réseau de communication propriétaire à très grande vitesse (processeurs massivement
parallèles) ou basé sur des technologies standard telles que gigabit Ethernet (fermes de
serveurs).

© HELMo Campus Guillemins Page 9.3


Les architectures à processeurs multiples Architecture des ordinateurs - Théorie

9.4 Processeur graphique (GPU)


Un processeur graphique (Graphics Processing Unit – GPU) est un processeur spécialisé dans la
création et la manipulation d’images.

Avec l’augmentation croissante des résolutions d’affichage, une image représente un volume de
données considérable. Ainsi, une image en résolution 4K (ultra haute définition) a une taille de 4096
× 3072 pixels, soit 12,6 mégapixels. Si chaque couleur rouge/vert/bleu est codée sur 8 bits, on
obtient un volume total de presque 40 Mo par image !

Un GPU part de la constatation que la génération ou le traitement d’une image consiste très souvent
à réaliser la même séquence d’opérations simultanément sur de nombreux points de l’image.

En simplifiant, on peut dire qu’un GPU est une architecture MIMD composée de nombreux
processeurs SIMD :

• Des unités de calcul distinctes peuvent effectuer simultanément des traitements différents
sur des portions distinctes d’une même image (traitement MIMD).
• Chaque unité de calcul est elle-même capable d’exécuter une même opération sur un grand
nombre de données simultanément (traitement SIMD) ;
• Enfin, l’architecture d’un GPU doit offrir une très grande bande passante entre la mémoire et
les unités de calcul afin de pouvoir acheminer l’énorme volume de données que représente
chaque image.

À titre d’illustration, nous reproduisons ci-dessous le schéma d’un GPU de chez NVIDIA basé sur
l’architecture Fermi.

Le GPU Fermi est constitué de 16 « streaming multiprocessor » (SM) qui partagent une mémoire
cache de niveau 2 (L2 Cache). Ce sont les 16 bandes verticales sur le schéma ci-dessous.

Figure 9-2 - Organisation interne du GPU NVIDIA Fermi

Page 9.4 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Les architectures à processeurs multiples

Chaque SM est lui-même constitué de 32 cœurs CUDA. Chaque cœur contient une unité
arithmétique et logique (ALU nombres entiers) et une unité FPU (Floating-Point Unit).

Figure 9-4 - CUDA Core

Figure 9-3 - Stream processor

Note : les figures sont extraites du White Paper de NVIDIA « NVIDIA’s Next Generation CUDA™
Compute Architecture : Fermi™ »

© HELMo Campus Guillemins Page 9.5


Les architectures à processeurs multiples Architecture des ordinateurs - Théorie

Page 9.6 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Bibliographie

Bibliographie
Le contenu de ce cours est principalement basé sur les livres de référence présentés ci-dessous.

La lecture d'un ou plusieurs de ces ouvrages vous permettra, si vous le souhaitez, d'approfondir vos
connaissances sur ce sujet passionnant que constitue l'architecture des ordinateurs.

Paolo Zanella, Yves Ligier, Emmanuel Lazard


« Architecture et technologie des ordinateurs »
5e édition, Ed. Dunod, 2013.

Andrew S. Tanenbaum, Todd Austin


« Structured Computer Organization »
sixth edition, Ed. Pearson, 2013.

David A. Patterson, John L. Hennessy


« Computer Organization and Design: The Hardware / Software
Interface »
fifth edition, Ed. Morgan Kaufmann, 2014.

Charles Petzold
« Code : The Hidden Language of Computer Hardware and Software »
first edition, Microsoft Press, 2000.

© HELMo Campus Guillemins B.1


Bibliographie Architecture des ordinateurs - Théorie

B.2 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Table des matières

Table des matières


1 HISTOIRE DE L’INFORMATIQUE ............................................................................................................. 1.1

1.1 DES NOMBRES ET DES HOMMES .................................................................................................................. 1.1


1.2 DEUX MILLÉNAIRES DE PROGRÈS… .............................................................................................................. 1.2
1.3 ÉVOLUTION DES ORDINATEURS ................................................................................................................... 1.3
1.3.1 Première génération : les tubes à vide (1945 – 1955) .................................................................... 1.3
1.3.2 Deuxième génération : les transistors (1955 – 1965) ..................................................................... 1.5
1.3.3 Troisième génération : les circuits intégrés (1965 – 1970) ............................................................. 1.5
1.3.4 Quatrième génération : les microprocesseurs (1970 – ????) ......................................................... 1.6
1.4 ÉVOLUTION DES PERFORMANCES ................................................................................................................ 1.7
1.4.1 La loi de Moore ............................................................................................................................... 1.7
1.4.2 Avantages et inconvénients de l’intégration à large échelle .......................................................... 1.8
1.4.3 Quelles sont les solutions envisageables ? ..................................................................................... 1.8

2 PRÉSENTATION GÉNÉRALE D’UN ORDINATEUR .................................................................................... 2.1

2.1 QU’EST-CE QU’UN ORDINATEUR ?............................................................................................................... 2.1


2.1.1 Définition d’un ordinateur .............................................................................................................. 2.1
2.1.2 Toute une gamme d’ordinateurs .................................................................................................... 2.2
2.1.3 L’informatique dans les nuages : le mainframe réinventé ! ........................................................... 2.4
2.1.3.1 Définition ............................................................................................................................................... 2.4
2.1.3.2 Intérêt .................................................................................................................................................... 2.4
2.1.3.3 Services « cloud » proposés aux entreprises ......................................................................................... 2.5
2.2 ORGANISATION INTERNE D’UN ORDINATEUR MONOPROCESSEUR....................................................................... 2.6
2.2.1 Organisation de base ..................................................................................................................... 2.6
2.2.2 L’unité centrale de traitement ........................................................................................................ 2.6
2.2.3 La mémoire centrale....................................................................................................................... 2.7
2.2.4 Les entrées et sorties ...................................................................................................................... 2.7
2.2.5 Organisation améliorée .................................................................................................................. 2.8
2.3 ARCHITECTURE EN COUCHES ...................................................................................................................... 2.8
2.4 ARCHITECTURES CISC ET RISC ................................................................................................................. 2.11

3 LE CODAGE DES INFORMATIONS .......................................................................................................... 3.1

3.1 SYSTÈMES DE NUMÉRATION ....................................................................................................................... 3.1


3.1.1 Systèmes de numération utilisés en informatique ......................................................................... 3.1
3.1.2 Formule générale de définition d’un nombre entier ....................................................................... 3.2
3.1.3 Formule générale de définition d’un nombre réel .......................................................................... 3.2
3.1.4 Opérations arithmétiques .............................................................................................................. 3.3
3.1.4.1 Addition et multiplication en décimal (base 10) .................................................................................... 3.3
3.1.4.2 Addition et multiplication en base quelconque..................................................................................... 3.4
3.1.5 Similitudes entre bases ................................................................................................................... 3.5
3.2 CONVERSION ENTRE BASES ........................................................................................................................ 3.7
3.2.1 Nombres entiers : base B vers décimal ........................................................................................... 3.7
3.2.2 Nombres entiers : décimal vers base B ........................................................................................... 3.7
3.2.2.1 Méthode 1 – Resserrement d’intervalle ................................................................................................ 3.7
3.2.2.2 Méthode 2 – Division par la base .......................................................................................................... 3.8
3.2.3 Bases qui sont des puissances de 2 ................................................................................................ 3.9
3.2.4 Nombres réels : base B vers décimal ............................................................................................ 3.10

© HELMo Campus Guillemins T.1


Architecture des ordinateurs - Théorie Table des matières

3.2.5 Nombres réels : décimal vers base B ............................................................................................ 3.10


3.3 REPRÉSENTATION INTERNE DES INFORMATIONS ........................................................................................... 3.12
3.3.1 Des bits, des octets et des mots ................................................................................................... 3.12
3.3.2 Signification d’une séquence de bits ............................................................................................ 3.12
3.4 REPRÉSENTATION DES NOMBRES ENTIERS ................................................................................................... 3.14
3.4.1 Décimal codé binaire .................................................................................................................... 3.14
3.4.1.1 Le code BCD (Binary Coded Decimal) .................................................................................................. 3.14
3.4.1.2 L’addition en BCD ................................................................................................................................ 3.14
3.4.2 Les nombres naturels ................................................................................................................... 3.15
3.4.3 Les nombres entiers relatifs.......................................................................................................... 3.16
3.4.3.1 Signe et valeur absolue........................................................................................................................ 3.16
3.4.3.2 Complément à 1 .................................................................................................................................. 3.17
3.4.3.3 Complément à 2 .................................................................................................................................. 3.17
3.4.3.4 Extension de signe ............................................................................................................................... 3.19
3.4.3.5 Représentation biaisée ........................................................................................................................ 3.19
3.4.4 Les représentations petit-boutiste et gros-boutiste ..................................................................... 3.20
3.5 REPRÉSENTATION DES NOMBRES RÉELS ...................................................................................................... 3.22
3.5.1 Virgule fixe.................................................................................................................................... 3.22
3.5.2 Virgule flottante ........................................................................................................................... 3.22
3.5.3 Conversion vers le format IEEE 754 .............................................................................................. 3.24
3.5.4 Conversion depuis le format IEEE 754 .......................................................................................... 3.25
3.5.5 Différences entre nombres réels et nombres en virgule flottante ................................................ 3.25
3.6 DONNÉES NON NUMÉRIQUES ................................................................................................................... 3.27
3.6.1 Introduction .................................................................................................................................. 3.27
3.6.2 EBCDIC (Extended Binary Coded Decimal Interchange Code) ...................................................... 3.27
3.6.3 ASCII (American Standard Code for Information Interchange) .................................................... 3.28
3.6.4 Unicode et représentation UTF-8 ................................................................................................. 3.28
3.6.5 Représentation des données dans les langages de programmation ............................................ 3.29
3.7 DÉTECTION ET CORRECTION D’ERREURS ...................................................................................................... 3.30
3.7.1 Introduction .................................................................................................................................. 3.30
3.7.2 Codes autovérificateurs (bit de parité) ......................................................................................... 3.30
3.7.3 Codes autocorrecteurs.................................................................................................................. 3.31
3.7.3.1 Double parité ....................................................................................................................................... 3.31
3.7.3.2 Code de Hamming ............................................................................................................................... 3.31
3.7.4 Détection d’erreurs groupées (CRC) ............................................................................................. 3.35
3.8 COMPRESSION DES DONNÉES ................................................................................................................... 3.36

4 LES CIRCUITS LOGIQUES ........................................................................................................................ 4.1

4.1 ALGÈBRE DE BOOLE ET PORTES LOGIQUES ..................................................................................................... 4.1


4.1.1 Introduction .................................................................................................................................... 4.1
4.1.2 Variables booléennes et fonctions logiques ................................................................................... 4.1
4.1.3 Opérateurs logiques et portes logiques.......................................................................................... 4.3
4.1.4 Implémentation physique des fonctions logiques .......................................................................... 4.4
4.1.5 Propriétés et théorèmes fondamentaux de l’algèbre de Boole ...................................................... 4.6
4.1.6 Formes normales ............................................................................................................................ 4.6
4.1.7 Synthèse d’un circuit logique à partir d’une table de vérité ........................................................... 4.7
4.1.8 NAND et NOR : opérateurs complets.............................................................................................. 4.9
4.2 CIRCUITS COMBINATOIRES ....................................................................................................................... 4.10
4.2.1 Définition ...................................................................................................................................... 4.10
4.2.2 Décodeur ...................................................................................................................................... 4.10
4.2.3 Multiplexeur ................................................................................................................................. 4.11

T.2 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Table des matières

4.2.3.1 Fonctionnement .................................................................................................................................. 4.11


4.2.3.2 Fonction universelle ............................................................................................................................ 4.12
4.2.4 Démultiplexeur ............................................................................................................................. 4.13
4.2.5 Comparateur ................................................................................................................................ 4.13
4.2.6 Additionneur................................................................................................................................. 4.14
4.3 UNITÉ ARITHMÉTIQUE ET LOGIQUE (ALU) .................................................................................................. 4.16
4.4 CIRCUITS ASYNCHRONES ET SYNCHRONES ................................................................................................... 4.18
4.4.1 Introduction .................................................................................................................................. 4.18
4.4.2 Horloge ......................................................................................................................................... 4.18
4.4.3 Circuit asynchrone ........................................................................................................................ 4.19
4.4.4 Circuit synchrone .......................................................................................................................... 4.19
4.5 CIRCUITS SÉQUENTIELS............................................................................................................................ 4.20
4.5.1 Définition ...................................................................................................................................... 4.20
4.5.2 Bascules et verrous ....................................................................................................................... 4.20
4.5.3 Bascule SR .................................................................................................................................... 4.21
4.5.3.1 Introduction......................................................................................................................................... 4.21
4.5.3.2 Les deux états stables de bascule SR ................................................................................................... 4.21
4.5.3.3 Transition d’un état à l’autre ............................................................................................................... 4.22
4.5.3.4 Instabilité de la bascule SR .................................................................................................................. 4.22
4.5.4 Bascule SR synchrone ................................................................................................................... 4.22
4.5.4.1 Introduction......................................................................................................................................... 4.22
4.5.4.2 Synchronisation sur un niveau de l’horloge ........................................................................................ 4.23
4.5.4.3 Synchronisation sur une transition de l’horloge .................................................................................. 4.23
4.5.5 Bascule D ...................................................................................................................................... 4.25
4.5.6 Registres de n bits ........................................................................................................................ 4.26
4.5.7 Mémoires ..................................................................................................................................... 4.26

5 L’UNITÉ CENTRALE DE TRAITEMENT (CPU) ............................................................................................ 5.1

5.1 INTRODUCTION ....................................................................................................................................... 5.1


5.2 CODE MACHINE ET LANGAGE D’ASSEMBLAGE................................................................................................. 5.1
5.2.1 Le code machine ............................................................................................................................. 5.1
5.2.2 Les registres du CPU ....................................................................................................................... 5.3
5.2.3 Le langage d’assemblage ............................................................................................................... 5.3
5.2.4 Les modes d’adressage................................................................................................................... 5.5
5.2.5 Particularités d’adressage du processeur MIPS ............................................................................. 5.7
5.2.6 Exemple d’un programme en langage d’assemblage .................................................................... 5.9
5.2.7 Exemple avancé : la suite de Fibonacci ........................................................................................ 5.10
5.3 CONSTRUIRE UN CHEMIN DE DONNÉES (DATAPATH)...................................................................................... 5.12
5.3.1 Objectif ......................................................................................................................................... 5.12
5.3.2 Le cycle d’instruction .................................................................................................................... 5.12
5.3.3 Obtention des instructions ........................................................................................................... 5.13
5.3.4 Instructions de type R ................................................................................................................... 5.13
5.3.5 Instructions de transfert avec la mémoire.................................................................................... 5.15
5.3.6 Instructions de branchement........................................................................................................ 5.17
5.3.7 Signaux de contrôle ...................................................................................................................... 5.18
5.3.8 Instructions de saut de type J ....................................................................................................... 5.18
5.3.9 Synchronisation du CPU ............................................................................................................... 5.18
5.4 PIPELINING ........................................................................................................................................... 5.19
5.4.1 Améliorer les performances ......................................................................................................... 5.19
5.4.2 Principe de fonctionnement ......................................................................................................... 5.20
5.4.3 Mise en œuvre dans un CPU ......................................................................................................... 5.21

© HELMo Campus Guillemins T.3


Architecture des ordinateurs - Théorie Table des matières

5.4.4 Limitations du pipelining .............................................................................................................. 5.23


5.4.4.1 Dépendance de données entre deux instructions ............................................................................... 5.23
5.4.4.2 Conflit de ressources ........................................................................................................................... 5.23
5.4.4.3 Branchement conditionnel .................................................................................................................. 5.23
5.4.5 Améliorations ............................................................................................................................... 5.24
5.4.5.1 Le « data forwarding »......................................................................................................................... 5.24
5.4.5.2 L’exécution dans le désordre ............................................................................................................... 5.24
5.4.5.3 L’exécution spéculative ....................................................................................................................... 5.25
5.5 PROCESSEUR VECTORIEL .......................................................................................................................... 5.25
5.6 ARCHITECTURE SUPER SCALAIRE ................................................................................................................ 5.25
5.7 EXCEPTIONS ET INTERRUPTIONS ................................................................................................................ 5.26
5.7.1 Définitions .................................................................................................................................... 5.26
5.7.2 Gestion des exceptions et des interruptions ................................................................................. 5.26

6 LES MÉMOIRES ..................................................................................................................................... 6.1

6.1 LA HIÉRARCHIE DES MÉMOIRES ................................................................................................................... 6.1


6.2 CARACTÉRISTIQUES DES MÉMOIRES ............................................................................................................. 6.3
6.3 MÉMOIRE CENTRALE ................................................................................................................................ 6.5
6.3.1 Classification des puces mémoires ................................................................................................. 6.5
6.3.2 Mémoire vive statique ou dynamique ............................................................................................ 6.6
6.3.3 Organisation physique ................................................................................................................... 6.7
6.4 MÉMOIRE DE MASSE ................................................................................................................................ 6.8
6.4.1 Les systèmes de stockage de masse ............................................................................................... 6.8
6.4.2 Les disques magnétiques ................................................................................................................ 6.9
6.4.3 Le système RAID ........................................................................................................................... 6.12
6.4.3.1 Introduction......................................................................................................................................... 6.12
6.4.3.2 Les bénéfices du système RAID ........................................................................................................... 6.12
6.4.4 Architectures de stockage ............................................................................................................ 6.15
6.5 MÉMOIRE CACHE (ANTÉMÉMOIRE) ........................................................................................................... 6.16
6.5.1 Introduction .................................................................................................................................. 6.16
6.5.2 Le principe de localité ................................................................................................................... 6.17
6.5.3 Fonctionnement d’une mémoire cache ........................................................................................ 6.17
6.5.3.1 Généralités .......................................................................................................................................... 6.17
6.5.3.2 Cache à correspondance directe (direct-mapped cache) .................................................................... 6.18
6.5.3.3 Cache complètement associative (fully-associative cache) ................................................................. 6.20
6.5.3.4 Cache associative par ensemble (set-associative cache) ..................................................................... 6.21
6.5.3.5 Algorithmes de remplacement ............................................................................................................ 6.22
6.5.3.6 Gestion des modifications ................................................................................................................... 6.23
6.6 MÉMOIRE VIRTUELLE .............................................................................................................................. 6.24
6.6.1 Implémentation de base............................................................................................................... 6.24
6.6.2 Implémentation complète ............................................................................................................ 6.25

7 LES ENTRÉES ET SORTIES ....................................................................................................................... 7.1

7.1 INTRODUCTION ....................................................................................................................................... 7.1


7.2 INTERRUPTIONS HIÉRARCHISÉES .................................................................................................................. 7.2
7.3 CONTRÔLEUR DE PÉRIPHÉRIQUE.................................................................................................................. 7.3
7.4 ACCÈS DIRECT À LA MÉMOIRE (DMA) .......................................................................................................... 7.3
7.5 CANAUX D’ENTRÉES/SORTIES ..................................................................................................................... 7.4
7.6 BUS DE COMMUNICATION ......................................................................................................................... 7.5
7.6.1 Généralités ..................................................................................................................................... 7.5
7.6.2 Les bus d’extension......................................................................................................................... 7.5

T.4 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Table des matières

7.6.3 Les bus externes ............................................................................................................................. 7.6


7.7 LES RÉSEAUX ........................................................................................................................................... 7.7
7.7.1 Avant-propos .................................................................................................................................. 7.7
7.7.2 Étendue d’un réseau ....................................................................................................................... 7.7
7.7.3 Méthodes de diffusion des données ............................................................................................... 7.7
7.7.4 Techniques de commutation de données ....................................................................................... 7.8
7.7.5 Topologie des réseaux .................................................................................................................... 7.9

8 LE SYSTÈME D’EXPLOITATION ............................................................................................................... 8.1

8.1 INTRODUCTION ....................................................................................................................................... 8.1


8.2 LE NOYAU .............................................................................................................................................. 8.2
8.3 SYSTÈMES MULTITÂCHES ........................................................................................................................... 8.2
8.4 GESTION DE LA MÉMOIRE .......................................................................................................................... 8.4
8.5 PROCESSUS ET THREADS ............................................................................................................................ 8.6

9 LES ARCHITECTURES À PROCESSEURS MULTIPLES ................................................................................. 9.1

9.1 INTRODUCTION ....................................................................................................................................... 9.1


9.2 DIFFÉRENTES FORMES DE PARALLÉLISME....................................................................................................... 9.2
9.3 CLASSIFICATION DES SYSTÈMES PARALLÈLES................................................................................................... 9.3
9.4 PROCESSEUR GRAPHIQUE (GPU) ................................................................................................................ 9.4

© HELMo Campus Guillemins T.5


Architecture des ordinateurs - Théorie Table des matières

T.6 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Table des figures

Table des figures


Figure 1-1 - Quelques systèmes de numération .................................................................................. 1.2
Figure 1-2 - L’architecture de von Neumann ....................................................................................... 1.4
Figure 1-3 - Illustration de la Loi de Moore .......................................................................................... 1.7
Figure 2-1 - Exemple d'ordinateur personnel ...................................................................................... 2.1
Figure 2-2 - Les différentes offres de services cloud ............................................................................ 2.5
Figure 2-3 - Organisation de base d'un ordinateur .............................................................................. 2.6
Figure 2-4 - Organisation améliorée d'un ordinateur .......................................................................... 2.8
Figure 2-5 - Structure en couches d'un ordinateur .............................................................................. 2.8
Figure 3-1 - Principaux systèmes de numération en informatique ...................................................... 3.1
Figure 3-2 - Table de conversion décimal/binaire/octal/hexadécimal ................................................ 3.2
Figure 3-3 - Table d’addition en décimal .............................................................................................. 3.3
Figure 3-4 - Table de multiplication en décimal ................................................................................... 3.4
Figure 3-5 - Tables d’addition et de multiplication en octal ................................................................ 3.4
Figure 3-6 - Tables d’addition et de multiplication en binaire ............................................................. 3.5
Figure 3-7 - Chiffres octal/hexadécimal et nombres binaires .............................................................. 3.9
Figure 3-8 - Code BCD......................................................................................................................... 3.14
Figure 3-9 - Représentations petit-boutiste et gros-boutiste ............................................................ 3.20
Figure 3-10 - Le code EBCDIC (extrait) ............................................................................................... 3.27
Figure 3-11 - Le code ASCII ................................................................................................................. 3.28
Figure 4-1 - Transistor .......................................................................................................................... 4.5
Figure 4-2 - Inverseur ........................................................................................................................... 4.5
Figure 4-3 - Portes logiques avec des transistors ................................................................................. 4.5
Figure 4-4 - Les opérateurs complets NAND et NOR............................................................................ 4.9
Figure 4-5 - Circuit décodeur « 2 vers 4 » .......................................................................................... 4.10
Figure 4-6 - Circuit multiplexeur « 4 vers 1 » ..................................................................................... 4.11
Figure 4-7 - Circuit démultiplexeur « 1 vers 4 » ................................................................................. 4.13
Figure 4-8 - Demi-additionneur .......................................................................................................... 4.14
Figure 4-9 - Additionneur complet ..................................................................................................... 4.14
Figure 4-10 - Schéma bloc d’un additionneur complet ...................................................................... 4.15
Figure 4-11 - Additionneur sur n bits ................................................................................................. 4.15
Figure 4-12 - Schéma bloc d'un additionneur sur 8 bits..................................................................... 4.15
Figure 4-13 - Unité arithmétique et logique simplifiée ...................................................................... 4.16
Figure 4-14 - ALU sur 4 bits ................................................................................................................ 4.17
Figure 4-15 - Signal d'horloge ............................................................................................................. 4.18
Figure 4-16 - Synchronisation sur un signal d'horloge ....................................................................... 4.19
Figure 4-17 - Variantes de bascules D synchrones ............................................................................. 4.19
Figure 4-18 - Synchronisation sur les niveaux haut et bas d'une horloge ......................................... 4.23
Figure 4-19 - Bascule SR synchrone sur niveau haut.......................................................................... 4.23
Figure 4-20 - Générateur d'impulsions sur transitions montantes .................................................... 4.24
Figure 4-21 - Bascule SR synchrone sur transition montante ............................................................ 4.24
Figure 4-22 - Bascule D synchrone sur niveau haut ........................................................................... 4.25

© HELMo Campus Guillemins T.7


Architecture des ordinateurs - Théorie Table des figures

Figure 4-23 - Bascule D synchrone sur transition descendante ......................................................... 4.25


Figure 4-24 - Registre de 4 bits........................................................................................................... 4.26
Figure 4-25 - Schéma bloc d'une mémoire de 4 mots ....................................................................... 4.27
Figure 4-26 - Schéma logique d’une mémoire de 4 x 4 bits ............................................................... 4.28
Figure 4-27 - Exemple de mémoire 16x8 ........................................................................................... 4.30
Figure 5-1 - Formats des instructions (code machine) ......................................................................... 5.2
Figure 5-2 - Les 32 registres du processeur MIPS ................................................................................ 5.3
Figure 5-3 - Résumé du langage d'assemblage MIPS ........................................................................... 5.4
Figure 5-4 - Branchement inconditionnel et absolu............................................................................. 5.7
Figure 5-5 - Découpage de la mémoire en blocs de 64M mots mémoire ............................................ 5.8
Figure 5-6 - Branchement conditionnel et relatif................................................................................. 5.9
Figure 5-7 - Chemin de données pour le séquencement des instructions ........................................ 5.13
Figure 5-8 - Chemin de données pour les instructions de type R ...................................................... 5.14
Figure 5-9 - Chemin de données pour les instructions de transfert mémoire ................................... 5.16
Figure 5-10 - Chemin de données complet ........................................................................................ 5.17
Figure 5-11 - Signaux de contrôle....................................................................................................... 5.18
Figure 5-12 - Travail en séquence ...................................................................................................... 5.20
Figure 5-13 - Travail à la chaîne / Pipelining ...................................................................................... 5.20
Figure 5-14 - Chemin de données avec pipeline ................................................................................ 5.21
Figure 6-1 - La hiérarchie des mémoires .............................................................................................. 6.2
Figure 6-2 - Préfixes décimaux et binaires ........................................................................................... 6.3
Figure 6-3 - Structure d'un disque magnétique ................................................................................... 6.9
Figure 6-4 - Organisation des secteurs sur une piste ......................................................................... 6.10
Figure 6-5 - Raid 0............................................................................................................................... 6.12
Figure 6-6 - Raid 1............................................................................................................................... 6.13
Figure 6-7 - Raid 2............................................................................................................................... 6.13
Figure 6-8 - Raid 3............................................................................................................................... 6.13
Figure 6-9 - Raid 4............................................................................................................................... 6.14
Figure 6-10 - Raid 5............................................................................................................................. 6.14
Figure 6-11 - Cache à correspondance directe................................................................................... 6.18
Figure 6-12 - Cache complètement associative ................................................................................. 6.20
Figure 6-13 - Cache associative par ensemble ................................................................................... 6.21
Figure 6-14 - Adresses virtuelles et physiques ................................................................................... 6.24
Figure 6-15 - Fonctionnement de la mémoire virtuelle ..................................................................... 6.25
Figure 7-1 - Architecture type d'un ordinateur .................................................................................... 7.1
Figure 7-2 - Accès direct à la mémoire ................................................................................................. 7.3
Figure 7-3 - Les canaux d'entrées/sorties ............................................................................................ 7.4
Figure 7-4 - Exemple d'architecture PCI Express .................................................................................. 7.6
Figure 9-1 - Classification de Flynn de architectures parallèles ........................................................... 9.3
Figure 9-2 - Organisation interne du GPU NVIDIA Fermi ..................................................................... 9.4
Figure 9-3 - Stream processor .............................................................................................................. 9.5
Figure 9-4 - CUDA Core......................................................................................................................... 9.5

T.8 © HELMo Campus Guillemins


Architecture des ordinateurs - Théorie Tables de conversion

Nombres de 0 à 15 Puissances de 2, 8 et 16
Décimal Hexa Binaire Octal Binaire n 2n 8n 16n
0 0 0000 0 000 -4 0,0625 0,000244140625 -
1 1 0001 1 001 -3 0,125 0,001953125 0,000244140625
2 2 0010 2 010 -2 0,25 0,015625 0,00390625
3 3 0011 3 011 -1 0,5 0,125 0,0625
4 4 0100 4 100 0 1 1 1
5 5 0101 5 101 1 2 8 16
6 6 0110 6 110 2 4 64 256
7 7 0111 7 111 3 8 512 4.096
8 8 1000 - - 4 16 4.096 65.536
9 9 1001 - - 5 32 32.768 1.048.576
10 A 1010 - - 6 64 262.144 16.777.216
11 B 1011 - - 7 128 2.097.152 268.435.456
12 C 1100 - - 8 256 16.777.216 4.294.967.296
13 D 1101 - - 9 512 134.217.728 68.719.476.736
14 E 1110 - - 10 1.024 1.073.741.824 -
15 F 1111 - - 11 2.048 8.589.934.592 -
12 4.096 68.719.476.736 -
13 8.192 549.755.813.888 -
14 16.384 - -
15 32.768 - -
Code ASCII (7 bits) - extrait 16 65.536 - -

Code Binaire Car Code Binaire Car


64 1000000 @ 96 1100000 `
Extraits de la « Greencard » - MIPS Reference DATA
65 1000001 A 97 1100001 a CORE INSTRUCTION SET
66 1000010 B 98 1100010 b Mne- For- Opcode
Name Operation
67 1000011 C 99 1100011 c monic mat / Funct
68 1000100 D 100 1100100 d Add add R R[rd]=R[rs]+R[rt] 0/20hex
69 1000101 E 101 1100101 e Add Immediate addi I R[rt]=R[rs]+SignExtImm 8hex
70 1000110 F 102 1100110 f If (R[rs]==R[rt])
Branch On Equal beq I 4hex
71 1000111 G 103 1100111 g PC=PC+4+BranchAddr
72 1001000 H 104 1101000 h Jump j J PC=JumpAddr 2hex
73 1001001 I 105 1101001 i Jump Register jr R PC=R[rs] 0/8hex
74 1001010 J 106 1101010 j Load Word lw I R[rt]=M[R[rs]+SignExtImm] 23hex
75 1001011 K 107 1101011 k Shift Left Logical sll R R[rd]=R[rt] << shamt 0/0hex
76 1001100 L 108 1101100 l Shift Right Logical srl R R[rd]=R[rt] >>> shamt 0/2hex
77 1001101 M 109 1101101 m Store Word sw I M[R[rs]+SignExtImm]=R[rt] 2Bhex
78 1001110 N 110 1101110 n Subtract sub R R[rd]=R[rs]-R[rt] 0/22hex
79 1001111 O 111 1101111 o
80 1010000 P 112 1110000 p REGISTERS
81 1010001 Q 113 1110001 q Name Number Use Preserv
82 1010010 R 114 1110010 r $zero 0 Constant value 0 NA
83 1010011 S 115 1110011 s $v0-$v1 2-3 Function results, expr. evaluation No
84 1010100 T 116 1110100 t $a0-$a3 4-7 Arguments No
85 1010101 U 117 1110101 u $t0-$t7 8-15 Temporaries No
86 1010110 V 118 1110110 v $s0-$s7 16-23 Saved temporaries Yes
87 1010111 W 119 1110111 w $t8-t9 24-25 Temporaries No
88 1011000 X 120 1111000 x
89 1011001 Y 121 1111001 y BASIC INSTRUCTION FORMATS
90 1011010 Z 122 1111010 z R opcode rs rt rd shamt funct
91 1011011 [ 123 1111011 { 31 26 25 21 20 16 15 11 10 6 5 0
92 1011100 \ 124 1111100 | I opcode rs rt immediate
93 1011101 ] 125 1111101 } 31 26 25 21 20 16 15 0
94 1011110 ^ 126 1111110 ~ J opcode address
95 1011111 _ 127 1111111 DEL 31 26 25 0

© HELMo Campus Guillemins T.9

You might also like