Les processeurs généraux actuels se répartissent en deux grandes catégories appelées CISC pour Complex Instruction Set Computer et RISC pour Reduced Instruction Set Computer. Les processeurs de ces deux catégories se distinguent par la conception de leurs jeux d'instructions. Les processeurs CISC possèdent un jeu étendu d'instructions complexes. Chacune de ces instructions peut effectuer plusieurs opérations élémentaires comme charger une valeur en mémoire, faire une opération arithmétique et ranger le résultat en mémoire. Au contraire, les processeurs RISC possèdent un jeu d'instructions réduit où chaque instruction effectue une seule opération élémentaire. Le jeu d'instructions d'un processeur RISC est plus uniforme. Toutes les instructions sont codées sur la même taille et toutes s'exécute dans le même temps (un cycle d'horloge en général). L'organisation du jeu d'instructions est souvent appelé ISA pour Instruction Set Architecture
La répartition des principaux processeurs dans les deux catégories est la suivante.
CISC | RISC |
---|---|
S/360 (IBM) VAX (DEC) 68xx, 680x0 (Motorola) x86, Pentium (Intel) |
Alpha (DEC) PowerPC (Motorola) MIPS PA-RISC (Hewlett-Packard) SPARC |
Dans les premiers temps de l'informatique, les ordinateurs étaient programmés en langage machine ou en assembleur. Pour faciliter la programmation, les concepteurs de micro-processeurs dotèrent ceux-ci d'instructions de plus en plus complexes permettant aux programmeurs de coder de manière plus concise et plus efficace les programmes.
Lorsque les premiers langages de haut niveau remplacèrent l'assembleur, cette tendance s'accentua. Les concepteurs de micro-processeurs s'efforcèrent de combler le fossé entre le langage machine et les langages de haut niveau. Des instructions proches des constructions typiques des langages de haut niveau furent ajoutés aux micro-processeurs. L'idée était de faciliter la compilation des langages de haut niveau au détriment de la complexité des micro-processeurs. On ajouta par exemple des instructions spécifiques pour les appels/retours de fonctions ou des instructions spéciales pour les boucles pour décrémenter un registre et faire un saut si le résultat est non nul, tout ça en une seule instruction machine.
Un élément qui favorisa cette complexification des micro-processeurs était le manque (à cause du prix) de mémoire et la lenteur de celle-ci. L'absence de beaucoup de mémoire force les programmes à être le plus compacts possible. Pour réduire le nombre d'instructions nécessaires à un programme, il faut que chaque instruction fasse plusieurs opérations élémentaires. La lenteur relative de la mémoire pousse aussi à avoir des instructions complexes. Il n'y a alors moins de codes d'instructions à lire en mémoire et le programme en est accéléré.
Comme la densité d'intégration des transistors était encore faible, les micro-processeurs possédaient très peu de registres internes. De plus, un grand nombre de registres auraient nécessité plus de bits pour coder les instructions. Pour compenser cette lacune en registres, certaines instructions étaient capables, par exemple, de charger deux valeurs en mémoire, de faire la somme et de ranger le résultat en mémoire. Il y avait de nombreux modes d'adressage et tous les modes d'adressages étaient possibles à toutes les instructions. On parle alors d'orthogonalité lorsque toutes les instructions peuvent utiliser tous les modes d'adressages. L'aboutissement de ce type de jeux d'instructions est celui du VAX.
La complexification des jeux d'instructions a pour effet de compliquer notablement la phase de décodage des instructions. On peux constater que sur certains micro-processeurs à jeu d'instructions complexe, la moitié des transistors sur la puce de silicium est consacrée au décodage des instructions et au contrôle de l'exécution de celles-ci.
Comme le décodage des instructions est rendu difficile par un jeu d'instructions complexes, l'exécution des instructions simples est ralenti par un décodage compliqué.
Lorsque le jeu d'instructions est complexe, la plupart des compilateurs n'utilisent pas tout le jeu d'instructions. Il se contentent souvent d'un nombre réduit d'instructions. Le résultat est que les instructions les plus puissantes sont très rarement utilisées. On arrive alors au paradoxe suivant. Les instructions complexes qui ne sont pratiquement pas utilisées ralentissent les instructions simples qui sont utilisées la plupart du temps.
Des études statistiques sur des programmes tels des systèmes d'exploitation ou des applications réelles ont montré les faits suivants.
L'apparition de l'architecture RISC vint de la volonté de favoriser au maximum les instructions simples qui constituent la grande partie des programmes. L'idée est de supprimer les instructions complexes et les modes d'adressage élaborés afin d'augmenter la fréquence d'horloge et d'augmenter ainsi la vitesse d'exécution de toutes les instructions. La fréquence d'horloge d'un micro-processeur est souvent dictée par les instructions les plus complexes qui prennent plus de temps.
La philosophie essentielle des processeurs RISC est d'avoir un nombre important de registres. Des instructions de chargement et de rangement avec quelques modes d'adressage sont les seules à faire les échanges avec la mémoire. Toutes les autres instructions travaillent uniquement avec les registres.
L'apparition des micro-processeurs RISC est en partie due l'augmentation de la mémoire disponible sur les ordinateurs. Celle-ci n'est plus une limitation à la taille des programme. Un autre facteur important est le fossé qui s'est creusé entre la vitesse des processeurs et celle de la mémoire. Les processeurs ont une fréquence d'horloge élevée par rapport à la vitesse de la mémoire. Chaque accès à la mémoire les pénalise. Ceci accentue le rôle d'un nombre important de registres qui évitent les accès à la mémoire. La lenteur de la mémoire est en partie compensée par la présence de caches faits de mémoires rapides. Ceux-ci sont très efficaces pour lire les instructions des programmes puisque ces accès à la mémoire se font à des cases mémoire contiguës.
Les principales caractéristiques des processeurs RISC sont les suivantes.
La simplification du jeu d'instructions a reporté une partie du travail sur le compilateur. Ce dernier joue un rôle essentiel dans l'optimisation du code engendré. Il doit en particulier gérer les points suivants.