Comparaison CISC/RISC

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

Historique

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.

Caractéristiques

Les principales caractéristiques des processeurs RISC sont les suivantes.

Codage uniforme des instructions
Toutes les instructions sont codées avec un même nombre de bits, généralement un mot machine. L'op-code se trouve à la même position pour toutes les instructions. Ceci facilite le décodage des instructions.
Registres indifférenciés et nombreux
Tous les registres peuvent être utilisés dans tous les contextes. Il n'y a par exemple pas de registre spécifique pour la pile. Les processeurs séparent cependant les registres pour les valeurs flottantes des autres registres.
Limitation des accès mémoire
Les seules instructions ayant accès à la mémoire sont les instructions de chargement et de rangement. Toutes les autres instructions opèrent sur les registres. Il en résulte une utilisation intensive des registres.
Nombre réduit de modes d'adressage
Il n'y pas de mode d'adressage complexe. Les modes d'adressages possibles sont généralement immédiat, direct, indirect et relatifs. Un registre est souvent fixé à la valeur 0 afin d'obtenir certains modes d'adressages simples comme cas particulier d'autres modes d'adressage.
Nombre réduit de types de données
Les seuls types de données supportés sont les entiers de différentes tailles (8, 16, 32 et 64 bits) et des nombres flottants en simple et double précision. Certains processeurs CISC comportent des instructions pour le traitement des chaînes de caractères, des polynômes ou des complexes

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.