5.2 Niveaux d'abstraction des ordinateurs
Objectifs d'apprentissage
À la fin de cette section, vous serez capable de :
- Décrire les niveaux d'abstraction du plus élevé au plus bas.
- Expliquer les abstractions des programmes d'application en relation avec les langages de haut niveau (HLL) et les architectures de jeu d'instructions.
- Discuter des abstractions des processeurs et de la manière dont la microarchitecture les prend en charge.
- Identifier le rôle du système d'exploitation dans l'abstraction.
- Discuter d'exemples de nouveaux systèmes informatiques disruptifs.
Lorsque vous regardez autour de vous, vous constatez que les systèmes complexes peuvent être considérés comme des couches d'abstractions. La suppression des éléments non importants d'un programme ou d'un code informatique qui détournent l'attention de son processus est appelée abstraction (abstraction). Cette façon d'appréhender les systèmes complexes facilite leur compréhension. Par exemple, les voitures sont des inventions très compliquées. Au plus haut niveau d'abstraction, nous considérons une voiture comme un ensemble de dispositifs utilisés pour la faire fonctionner, tels qu'un volant, des pédales de frein et d'accélérateur, etc. Si nous descendons à un niveau inférieur, nous voyons les dispositifs qui alimentent la voiture, tels que son moteur, ses engrenages et ses bougies d'allumage. Si nous prenons ces pièces et examinons leur conception, nous sommes alors à un niveau encore plus bas où nous voyons des métaux, des plastiques et d'autres matériaux. La même approche peut être appliquée aux ordinateurs pour comprendre leur fonctionnement. Nous pouvons considérer les ordinateurs comme plusieurs couches d'abstractions, comme le montre la Figure 5.5. Pour le reste de cette section, nous partirons du niveau le plus élevé, puis nous parcourrons chaque couche d'abstraction pour illustrer comment elle est utilisée comme bloc de construction par la couche précédente.
Les ordinateurs ne sont qu'un outil utilisé pour résoudre un problème. Vous pouvez utiliser des ordinateurs pour jouer à des jeux ou écouter de la musique, et dans ces cas, les problèmes que l'ordinateur essaie de résoudre sont associés à des programmes que vous utilisez à des fins de divertissement.
La ligne supérieure de la Figure 5.5 commence par le problème ; nous devons avoir une définition très précise du problème que nous essayons de résoudre avec un ordinateur. Ainsi, la première étape pour résoudre un problème avec un ordinateur est de savoir exactement, et sans aucune ambiguïté, ce que nous essayons de résoudre. Vous ne pouvez pas faire en sorte qu'un ordinateur résolve un problème à moins qu'il n'y ait un ensemble d'instructions défini et reproductible pour résoudre le problème. Vous vous demandez peut-être alors pourquoi il est nécessaire d'utiliser un ordinateur en premier lieu si vous pouvez résoudre le problème vous-même. Eh bien, les ordinateurs ne s'ennuient pas, sont précis et peuvent traiter de très gros problèmes. C'est pourquoi, l'étape suivante après la définition du problème est de définir les étapes de résolution du problème. Cette disposition de la solution est appelée un algorithme. L'algorithme est écrit en format libre ; c'est-à-dire qu'il peut s'agir d'étapes écrites sous forme de liste à puces, d'un organigramme ou d'une série d'équations mathématiques. Quel que soit le format que vous choisissez pour écrire l'algorithme, l'algorithme doit posséder un ensemble de caractéristiques clés.
La première caractéristique est qu'un algorithme doit être non ambigu. Chaque étape de l'algorithme doit être très bien définie et précise. La deuxième caractéristique est que l'algorithme doit être déterministe pour être reproductible et répétable, de sorte que le même ensemble d'entrées produise la même sortie. La troisième caractéristique est que l'algorithme, lorsqu'il est implémenté sur un ordinateur, doit consommer une quantité raisonnable de temps et de stockage en fonction des besoins du problème. Par exemple, un algorithme peut être fini et précis, mais s'il nécessite 100 ans pour générer un résultat, il est clairement inutile. Par exemple, un algorithme qui compte le nombre de nombres pairs n'est pas fini car nous avons un nombre infini de nombres pairs.
En supposant que nous ayons un algorithme, nous devons ensuite le préparer pour son exécution sur l'ordinateur. Tout d'abord, nous devons préparer l'entrée avant qu'elle ne soit prête à être consommée par l'ordinateur, nous confions donc l'algorithme à un programmeur dont le travail est de lire l'algorithme, de le comprendre, puis d'écrire un programme dans un langage informatique connu tel que C/C++ ou Python. Le programme indique à l'ordinateur ce qu'il doit faire, mais de manière formelle plutôt que libre comme un algorithme. À ce stade, nous passons à un autre niveau d'abstraction.
Abstractions des programmes d'application
Ensuite, le programmeur écrit un programme. La principale différence entre un algorithme et un programme est que le premier est écrit par un concepteur d'algorithmes et le second par un programmeur afin que le programme puisse être exécuté par une machine. Ces programmes sont appelés programmes d'application, ou simplement programmes, et il en existe des milliards aujourd'hui. Une fois que le programmeur a fini d'écrire le programme, il y a deux étapes supplémentaires avant qu'il ne puisse être exécuté par un ordinateur.
Langage de programmation de haut niveau
Le programme généré à l'étape précédente est écrit dans un langage de programmation. Il existe actuellement de nombreux langages de programmation dans le monde. Un langage de haut niveau (HLL) est la méthode la plus évoluée par laquelle un humain peut indiquer à un ordinateur comment effectuer des tâches et des applications. L'expression haut niveau signifie qu'il est plus proche d'un langage naturel que d'un langage de niveau machine tel que des chaînes de 1 et de 0. C'est-à-dire que le HLL est plus convivial et il est conçu pour faciliter la vie du programmeur, quel que soit le matériel ou la machine. Si vous regardez le code d'un programme, vous constatez qu'il est toujours en anglais, mais une version restreinte de l'anglais avec des mots-clés et des formats très spécifiques pour supprimer l'ambiguïté qui existe habituellement dans le langage humain naturel.
Même si les HLL s'appuient sur des versions restrictives de l'anglais, ils utilisent toujours l'anglais à un niveau élevé. La machine ne comprend pas l'anglais et a besoin d'un langage de bas niveau ; par conséquent, nous avons besoin d'une autre étape : le langage d'assemblage.
Questions de réflexion
Cent ou Un ?
Puisque les HLL visent à faciliter la vie des programmeurs, pourquoi avons-nous de nombreux HLL ? Pourquoi pas un seul langage que tous les programmeurs utiliseraient ?
Les langages de programmation sont généralement conçus pour aider à créer des programmes lisibles. Cependant, certains langages sont conçus avec des applications spécifiques à l'esprit. C'est-à-dire que certains langages de programmation sont plus faciles à utiliser pour concevoir des jeux, tandis que d'autres langages sont destinés à résoudre des problèmes mathématiques ou d'intelligence artificielle. Cependant, nous pouvons écrire n'importe quel programme dans n'importe quel langage. Mais notre tâche sera plus facile si nous utilisons le langage conçu pour des applications spécifiques.
Langage d'assemblage
Lorsque vous examinez la plupart des langages de programmation courants, vous trouvez des constructions telles que des fonctions, des méthodes, des sous-routines et des objets. Ces concepts ont été inventés pour aider les êtres humains (les programmeurs) à écrire leurs programmes après avoir compris l'algorithme. Les langages de haut niveau facilitent la vie des programmeurs. En utilisant des fonctions, des objets et d'autres constructions, les programmeurs peuvent écrire des programmes plus rapidement et les rendre compréhensibles et réutilisables pour d'autres. Les ordinateurs, en revanche, ont besoin d'instructions spécifiques pour effectuer des tâches (par exemple, ajouter ce nombre à cet autre nombre et stocker le résultat à cet endroit). Écrire des programmes de cette manière n'est pas facile pour les programmeurs car c'est source d'erreurs, cela prend beaucoup de temps à écrire correctement et ce n'est pas portable d'un ordinateur à l'autre. Alors, comment gérons-nous ces exigences contradictoires pour les programmeurs et les ordinateurs ? La réponse est les compilateurs.
Un compilateur est un logiciel qui prend un programme écrit dans un HLL donné et génère un autre programme qui effectue la même tâche que le programme initial mais est écrit dans un langage beaucoup plus convivial pour l'ordinateur, appelé langage d'assemblage. Le langage d'assemblage est ensuite traduit en code machine afin que le programme puisse être exécuté (Figure 5.7).
Un langage de bas niveau conçu pour être convivial pour l'ordinateur plutôt que pour l'humain est appelé langage d'assemblage (assembly language). Il n'utilise pas toutes les constructions que l'on trouve dans les HLL, telles que les objets ou les structures de données sophistiquées, ce qui pose deux défis.
Le premier défi est de gérer la sortie du compilateur, qui est un programme en langage d'assemblage que vous pouvez ouvrir et lire. Il s'agit essentiellement d'un fichier texte, il est donc écrit en anglais. Rappelez-vous, les ordinateurs ne comprennent pas l'anglais ; ils ne comprennent que les 1 et les 0. Pour relever ce défi, nous utilisons un autre programme, montré dans la Figure 5.5, appelé un assembleur (notez que les compilateurs peuvent invoquer directement les assembleurs). L'assembleur (assembler) prend en entrée le programme d'assemblage généré par le compilateur, et en sortie, un fichier qui contient l'équivalent de ce programme d'assemblage en termes de 1 et de 0. Ce fichier généré n'est plus en anglais, et vous ne pouvez pas l'ouvrir avec votre éditeur de texte préféré. Il est appelé un fichier de langage machine. C'est le fichier qu'un ordinateur comprend. La Figure 5.8 montre un exemple de programme écrit dans un HLL (en fait, un langage de niveau intermédiaire, qui est le langage de programmation C), qui est ensuite traduit en langage d'assemblage x86, puis en binaire (voir Chapitre 4 Réalisation linguistique des algorithmes : langages de programmation de bas niveau).
Le deuxième défi concerne la gestion du langage d'assemblage lui-même. Si vous regardez le programme en langage d'assemblage, vous constatez qu'il se compose d'instructions telles que add, divide et jump. Mais ces instructions sont-elles reconnues par tous les processeurs (c'est-à-dire la partie principale de l'ordinateur qui exécute le programme) du monde ? Si vous donnez ces instructions à un processeur tel qu'Intel, AMD, ARM, Qualcomm ou IBM Power, les reconnaîtront-ils tous ? La réponse dépend d'un nouveau concept appelé architecture de jeu d'instructions.
Architecture de jeu d'instructions
L'architecture de jeu d'instructions (ISA) est l'ensemble des instructions reconnues par chaque famille de processeurs. Par exemple, les processeurs Intel et AMD utilisent la même ISA, appelée x86-64, qui est différente de l'ISA reconnue par ARM ou IBM. Cela nous amène à revoir le concept de compilateurs. Un compilateur prend en entrée un programme écrit dans un HLL, et nous avons un compilateur pour chaque HLL. La sortie du compilateur est un programme d'assemblage dans une ISA spécifique, et nous avons un compilateur pour chaque ISA différente (par exemple, ISA 1 et ISA 2). Ainsi, si nous avons des programmes écrits dans trois HLL et que nous devons générer de l'assemblage pour des processeurs de deux familles différentes, alors nous avons besoin de six compilateurs comme le montre le Tableau 5.1.
| Compilateur n° | Entrée du compilateur | Sortie du compilateur |
|---|---|---|
| 1 | HLL 1 | ISA 1 |
| 2 | HLL 2 | ISA 2 |
| 3 | HLL 3 | ISA 1 |
| 4 | HLL 1 | ISA 2 |
| 5 | HLL 2 | ISA 1 |
| 6 | HLL 3 | ISA 2 |
Comme nous l'avons vu précédemment, la sortie du compilateur est l'entrée de l'assembleur, nous avons donc besoin d'assembleurs pour chaque ISA existante afin de générer un fichier de langage machine (par exemple, un fichier .exe) que le processeur peut exécuter.
Abstractions du processeur
Lorsque nous franchissons la couche de l'ISA dans la Figure 5.5, nous franchissons la frontière entre le logiciel et le matériel. Avant de discuter du matériel, nous devons comprendre deux mots : traducteur et interpréteur. Les deux mots signifient « traduire d'une langue 1 à une langue 2 », quelles que soient ces langues. La principale différence est le processus par lequel la traduction est effectuée. Un traducteur prend un programme entier dans la langue 1 et génère un autre programme dans la langue 2. Par exemple, le compilateur prend un HLL en entrée (langue 1) et génère le programme en langage d'assemblage correspondant (langue 2). L'interpréteur prend une ligne (ou commande) dans le programme en langue 1 et génère une (ou plusieurs) instructions dans la langue 2. Python est un exemple populaire de langage interprété.
Comprendre le niveau matériel nous permet de voir comment les ordinateurs exécutent les programmes. La partie principale du matériel informatique qui effectue l'exécution est appelée le processeur. Le processeur prend une instruction du fichier de langage machine, l'exécute et écrit les résultats dans un emplacement désigné. Ensuite, il récupère l'instruction suivante et fait de même. Il continue ainsi jusqu'à ce que le programme se termine ou qu'une erreur se produise. Il s'agit d'une simplification excessive, mais elle transmet l'idée générale. Comme vous pouvez le voir, il prend une instruction à la fois, c'est pourquoi la flèche verticale sortant de la boîte de langage machine dans la Figure 5.5 montre le mot interpréteur. Mais comment le processeur fait-il son travail de récupération et d'exécution d'une instruction ? Pour répondre à cette question, nous devons examiner les principaux composants d'un processeur.
Lien vers l'apprentissage
Le transistor (transistor) est le bloc de construction du matériel de tout ordinateur. Un transistor est simplement un interrupteur marche/arrêt ; lorsqu'il est allumé, il laisse passer le courant électrique. Lorsqu'il est éteint, il bloque le courant électrique. C'est très similaire à l'interrupteur d'éclairage que vous trouvez dans votre chambre. Mais avec ces transistors, nous pouvons faire plus : avec les transistors, nous construisons des ordinateurs. Lisez cet article pour en savoir plus sur les transistors et leur fonctionnement.
Microarchitecture
L'architecture (c'est-à-dire la conception) du microprocesseur (c'est-à-dire le processeur) est appelée microarchitecture (microarchitecture) (Figure 5.9). Son rôle principal est de concevoir les différents composants du processeur et de décider comment les connecter afin que le processeur puisse faire son travail. Par exemple, une pièce importante à l'intérieur du processeur est la partie qui récupère l'instruction suivante du programme. Une autre partie cruciale, appelée unité de contrôle, est responsable du décodage, ou de la compréhension, de ce que cette instruction veut faire, puis elle indique aux autres composants du processeur d'exécuter cette instruction. Ainsi, le travail de l'unité de contrôle est de prendre une instruction en entrée et de générer des signaux pour contrôler le reste du processeur afin de lui faire exécuter les instructions. D'autres parties du processeur incluent les unités d'exécution qui effectuent les calculs réels tels que la division, la multiplication, l'addition et la soustraction.
En résumé, à l'intérieur du processeur, vous trouvez ces différentes pièces qui récupèrent les instructions, les décodent et les exécutent. Mais qu'y a-t-il à l'intérieur de chacune de ces boîtes noires ?
Abstraction de la logique numérique
Le principal bloc de construction qui forme le processeur est appelé une porte logique (logic gate). Il existe très peu de types de portes logiques : ET, OU, NON, NON-ET, NON-OU, OU exclusif et NON-OU exclusif. En utilisant ces portes, et la plupart du temps seulement un sous-ensemble d'entre elles, vous pouvez concevoir toutes les pièces qui forment le processeur discuté précédemment. Mais qu'y a-t-il à l'intérieur de ces portes ? Comment sont-elles construites ?
Le niveau d'abstraction le plus bas
Le principal bloc de construction de toutes les portes logiques, et donc de tous les processeurs, est le transistor. Ceci est montré en bas de la Figure 5.5 comme niveau de dispositif. Bien que vous ayez peut-être déjà entendu le mot transistor, vous ne savez peut-être pas exactement ce qu'il fait. En termes simples, un transistor est un interrupteur marche/arrêt. C'est très similaire à l'interrupteur de lumière de votre maison qui peut allumer ou éteindre une lumière. Un transistor (transistor) laisse passer un courant électrique, l'état ON, ou peut bloquer le courant électrique, l'état OFF. Les transistors sont activés/désactivés en fonction de la tension d'entrée du transistor. Si la tension est supérieure à un seuil, le transistor est à l'état ON. Sinon, il est à l'état OFF. Il n'y a que deux états : ON/OFF, qui correspondent à 1 et 0. C'est pourquoi les ordinateurs ne comprennent que les 1 et les 0. En interconnectant plusieurs transistors d'une certaine manière, nous construisons une porte ET. Si nous les connectons d'une manière différente, nous construisons une porte OU, et ainsi de suite.
Si nous essayons de voir comment les transistors sont construits et fonctionnent, nous passons au niveau des semi-conducteurs. À ce niveau, nous utilisons un matériau spécial tel que le silicium et un processus spécial, et très coûteux, pour le transformer en un transistor fonctionnel. Un seul processeur contient des milliards de transistors. Comment un matériau comme le silicium peut-il fabriquer un transistor ? Cela nous amène au niveau des atomes et de la physique quantique.
Le rôle du système d'exploitation
Maintenant que nous avons parcouru la définition du problème jusqu'à la physique quantique, vous vous demandez où le système d'exploitation (OS) (c'est-à-dire OS X, Windows, Linux) s'inscrit dans ce schéma plus large. L'OS est similaire à tout programme d'application dans le sens où il doit être écrit dans un HLL, généralement C/C++, et passé par le compilateur et l'assembleur pour générer du code machine (machine code). Cependant, l'OS diffère des programmes d'application traditionnels en ce qu'il a plus de privilèges dans le système informatique (computer system).
Le système d'exploitation (OS), montré dans la Figure 5.10, est le seul logiciel qui peut accéder directement au matériel. Tout autre programme qui a besoin d'accéder au matériel, comme imprimer quelque chose, doit communiquer avec l'OS, et l'OS exécute la tâche demandée au nom du programme. La raison pour laquelle tous les ordinateurs sont conçus de cette manière est d'accroître la sécurité (un seul programme gère le matériel afin que les autres programmes ne puissent pas affecter la machine) et la fiabilité (un programme ne peut pas affecter une pièce de matériel, ce qui affecterait alors d'autres programmes). Pour que l'OS fasse son travail efficacement, il stocke les données et les programmes sur le disque de manière organisée en utilisant un système de fichiers. Le système de fichiers aide à organiser les fichiers afin qu'il soit plus facile de les trouver en cas de besoin.
Un fichier est un nom générique pour toute entité que nous voulons stocker dans l'ordinateur. Par exemple, tout programme que vous utilisez se compose d'un ou plusieurs fichiers. Chaque chanson que vous écoutez est un fichier. Toute image ou vidéo que vous regardez est un fichier, et ainsi de suite. Le processus par lequel l'OS gère quel programme utiliser avec quelle partie du matériel à un moment donné est appelé ordonnancement (scheduling). C'est-à-dire que l'OS décide quand votre navigateur web doit utiliser le processeur et quand votre lecteur multimédia utilise l'écran ou le haut-parleur. Il existe un nom générique pour tous les programmes exécutés sur votre ordinateur : processus. Donc, si vous écoutez de la musique tout en naviguant sur le web, vous utilisez deux processus : votre lecteur multimédia et votre navigateur. Par conséquent, une partie du travail de l'OS est l'ordonnancement des processus.
La technique que l'OS utilise pour isoler les différents programmes les uns des autres afin qu'ils n'écrasent pas les données des autres ou ne corrompent pas les fichiers des autres est appelée mémoire virtuelle (virtual memory). De plus, l'OS peut exploiter plusieurs ordinateurs, appelés machines virtuelles, ensemble pour agir comme un seul grand ordinateur et servir plusieurs utilisations en même temps. Les utilisateurs peuvent penser qu'ils ont le contrôle de toute la machine, même si la réalité n'est pas telle. C'est pourquoi cette technologie utilisée par l'OS est appelée machine virtuelle.
Il existe de nombreux OS dans le monde, mais les plus célèbres sont Windows de Microsoft, macOS d'Apple et Linux.
Nouvelles abstractions de systèmes informatiques disruptifs
Presque tous les ordinateurs du monde sont conçus de la manière que nous avons apprise jusqu'à présent et impliquent des niveaux d'abstraction (abstraction) très similaires. Cependant, il existe des conceptions très futuristes avec lesquelles les scientifiques expérimentent aujourd'hui et qui diffèrent des transistors traditionnels. Les scientifiques essaient, par exemple, de construire des ordinateurs en utilisant l'ADN. Nous avons l'informatique à ADN, et nous avons également un prototype de stockage à ADN.
Nous avons plusieurs prototypes de diverses entreprises d'informatique quantique où, au lieu d'utiliser des bits, 1 et 0, les machines utilisent des bits quantiques (qubits) qui prennent une valeur entre 1 et 0. Nous ne devons pas oublier que les ordinateurs traditionnels fonctionnent généralement en état binaire (c'est-à-dire en utilisant 0 et 1). Pour utiliser ces ordinateurs, nous devons construire différents types de compilateurs, de systèmes d'exploitation, de langages de programmation, et ainsi de suite. Une autre forme d'ordinateur non traditionnel est un ordinateur neuromorphique (neuromorphic computer), qui est construit pour agir comme une version simplifiée du cerveau. Il se compose donc de neurones matériels connectés entre eux. Ces ordinateurs ne sont pas programmés mais entraînés. À quoi ressembleront les ordinateurs dans 100 ans ? Nous ne le savons pas encore.