Berkeley RISC est l'un des deux projets de recherche fondamentaux sur la conception de microprocesseurs basés sur des ordinateurs à jeu d'instructions réduit (RISC) qui se déroulent dans le cadre du projet VLSI de la Defense Advanced Research Projects Agency . RISC a été dirigé par David Patterson (qui a inventé le terme RISC) à l' Université de Californie à Berkeley entre 1980 et 1984. L'autre projet a eu lieu non loin de là, à l'Université de Stanford, dans le cadre de leur effort MIPS qui a débuté en 1981 et s'est poursuivi jusqu'en 1984.
Le projet de Berkeley a connu un tel succès qu'il est devenu le nom de tous les modèles similaires qui ont suivi ; même le MIPS est devenu connu sous le nom de « processeur RISC ». La conception RISC de Berkeley a ensuite été commercialisée par Sun Microsystems sous le nom d' architecture SPARC et a inspiré l' architecture ARM .
Le concept RISC
Le RISC et le MIPS ont tous deux été développés à partir du constat que la grande majorité des programmes n'utilisaient qu'une petite minorité du jeu d'instructions disponible d'un processeur. Dans un article célèbre de 1978, Andrew S. Tanenbaum a démontré qu'un programme complexe de haut niveau de 10 000 lignes pouvait être représenté à l'aide d'une architecture de jeu d'instructions simplifiée utilisant un opcode de longueur fixe de 8 bits. C'était à peu près la même conclusion à laquelle était parvenue IBM , dont les études sur leur propre code exécuté sur des ordinateurs centraux comme l' IBM 360 n'utilisaient qu'un petit sous-ensemble de toutes les instructions disponibles. Ces deux études suggéraient qu'il était possible de produire un processeur beaucoup plus simple qui exécuterait toujours la plupart des codes du monde réel. Une autre découverte, pas entièrement explorée à l'époque, était la note de Tanenbaum selon laquelle 81 % des constantes étaient soit 0, 1 ou 2.
Ces réalisations ont eu lieu alors que le marché des microprocesseurs passait de 8 à 16 bits, avec l'apparition de modèles 32 bits. Ces modèles étaient basés sur l'objectif de reproduire certains des ISA existants les plus respectés du monde des ordinateurs centraux et des mini-ordinateurs. Par exemple, le NS32000 de National Semiconductor a commencé comme un effort pour produire une implémentation monopuce du VAX-11 , qui avait un riche jeu d'instructions avec une grande variété de modes d'adressage . Le Motorola 68000 était similaire dans sa disposition générale. Pour fournir ce riche ensemble d'instructions, les processeurs utilisaient un microcode pour décoder l'instruction visible par l' utilisateur en une série d'opérations internes. Ce microcode représentait peut-être 1/4 à 1/3 des transistors de la conception globale .
Si, comme le suggéraient ces autres articles, la majorité de ces opcodes ne seraient jamais utilisés en pratique, alors cette ressource importante serait gaspillée. Si l'on construisait simplement le même processeur en supprimant les instructions inutilisées, il serait plus petit et donc moins cher, tandis que si l'on utilisait plutôt ces transistors pour améliorer les performances au lieu de décoder des instructions qui ne seraient pas utilisées, un processeur plus rapide était possible. Le concept RISC consistait à tirer parti de ces deux avantages, en produisant un processeur ayant le même niveau de complexité que le 68000, mais beaucoup plus rapide.
Pour ce faire, RISC s'est concentré sur l'ajout de nombreux registres supplémentaires , de petits morceaux de mémoire contenant des valeurs temporaires auxquelles on peut accéder très rapidement. Cela contraste avec la mémoire principale normale , dont l'accès peut prendre plusieurs cycles. En fournissant plus de registres et en s'assurant que les compilateurs les utilisent réellement, les programmes devraient s'exécuter beaucoup plus rapidement. De plus, la vitesse du processeur serait plus étroitement définie par sa vitesse d'horloge, car il passerait moins de temps à attendre les accès à la mémoire. Transistor pour transistor, une conception RISC surpasserait un processeur conventionnel.
L'inconvénient était que les instructions supprimées exécutaient généralement plusieurs « sous-instructions ». Par exemple, l' ADDinstruction d'une conception traditionnelle se déclinait généralement en plusieurs versions : une qui additionnait les nombres de deux registres et les plaçait dans un troisième, une autre qui additionnait les nombres trouvés dans la mémoire principale et mettait le résultat dans un registre, etc. Les conceptions RISC, en revanche, n'incluaient qu'une seule version d'une instruction particulière, la ADD, par exemple, utilisait toujours des registres pour tous les opérandes. Cela obligeait le programmeur à écrire des instructions supplémentaires pour charger les valeurs depuis la mémoire, si nécessaire, ce qui rendait un programme RISC « moins dense ».
À l'époque où la mémoire était coûteuse, c'était un véritable problème, notamment parce que la mémoire était également beaucoup plus lente que le processeur. Étant donné qu'une conception RISC ADDnécessitait en fait quatre instructions (deux chargements, un ajout et une sauvegarde), la machine devait accéder à la mémoire beaucoup plus souvent pour lire les instructions supplémentaires, ce qui la ralentissait potentiellement considérablement. Cela était compensé dans une certaine mesure par le fait que les nouvelles conceptions utilisaient ce qui était alors un très grand mot d'instruction de 32 bits , ce qui permettait d'intégrer directement de petites constantes dans l'instruction au lieu de devoir les charger séparément. De plus, les résultats d'une opération sont souvent utilisés peu de temps après par une autre, donc en sautant l'écriture en mémoire et en stockant le résultat dans un registre, le programme n'était pas beaucoup plus volumineux et pouvait en théorie s'exécuter beaucoup plus rapidement. Par exemple, une chaîne d'instructions effectuant une série d'opérations mathématiques pouvait ne nécessiter que quelques chargements de mémoire, tandis que la majorité des nombres utilisés seraient soit des constantes dans les instructions, soit des valeurs intermédiaires laissées dans les registres à partir de calculs antérieurs. Dans un sens, dans cette technique, certains registres sont utilisés pour masquer les emplacements de mémoire, de sorte que les registres sont utilisés comme proxy pour les emplacements de mémoire jusqu'à ce que leurs valeurs finales après qu'un groupe d'instructions ait été déterminé.
Pour l'observateur occasionnel, il n'était pas certain que le concept RISC améliorerait les performances, et il pourrait même les aggraver. La seule façon d'en être sûr était de le simuler. Les résultats de ces simulations étaient clairs ; test après test, chaque simulation a montré un énorme avantage global en termes de performances grâce à cette conception.
Les deux projets, RISC et MIPS, différaient dans la gestion des registres. MIPS ajoutait simplement de nombreux registres et laissait aux compilateurs (ou aux programmeurs en langage assembleur ) le soin de les utiliser. RISC, en revanche, ajoutait des circuits au processeur pour assister le compilateur. RISC utilisait le concept de fenêtres de registres , dans lequel l'ensemble du « fichier de registres » était divisé en blocs, permettant au compilateur de « voir » un bloc pour les variables globales et un autre pour les variables locales.
L'idée était de rendre une instruction particulièrement courante, l' appel de procédure , extrêmement facile à mettre en œuvre. Presque tous les langages de programmation utilisent un système appelé enregistrement d'activation ou cadre de pile pour chaque procédure, qui contient l'adresse à partir de laquelle la procédure a été appelée, les données (paramètres) qui ont été transmises et l'espace pour les valeurs de résultat qui doivent être renvoyées. Dans la grande majorité des cas, ces cadres sont petits, généralement avec trois entrées ou moins et une ou aucune sortie (et parfois une entrée est réutilisée comme sortie). Dans la conception de Berkeley, une fenêtre de registre était donc un ensemble de plusieurs registres, suffisamment nombreux pour que l'ensemble du cadre de pile de procédure tienne probablement entièrement dans la fenêtre de registre.
Dans ce cas, l'appel et le retour d'une procédure sont simples et extrêmement rapides. Une seule instruction est appelée pour configurer un nouveau bloc de registres (une nouvelle fenêtre de registres), puis, avec les opérandes passés à la procédure dans la « partie basse » de la nouvelle fenêtre, le programme passe à la procédure. Au retour, les résultats sont placés dans la fenêtre à la même extrémité et la procédure se termine. Les fenêtres de registres sont configurées pour se chevaucher aux extrémités, de sorte que les résultats de l'appel « apparaissent » simplement dans la fenêtre de l'appelant, sans qu'aucune donnée ne doive être copiée . Ainsi, l'appel de procédure commun n'a pas besoin d'interagir avec la mémoire principale, ce qui l'accélère considérablement.
L'inconvénient de cette approche est que les procédures comportant un grand nombre de variables locales sont problématiques, et celles qui en comportent moins conduisent à un gaspillage de registres, une ressource coûteuse. Le nombre de fenêtres de registres dans la conception est limité, par exemple huit, de sorte que les procédures ne peuvent être imbriquées qu'à ce nombre de niveaux avant que le mécanisme de fenêtrage des registres n'atteigne sa limite ; une fois la dernière fenêtre atteinte, aucune nouvelle fenêtre ne peut être configurée pour un autre appel imbriqué. Et si les procédures ne sont imbriquées qu'à quelques niveaux de profondeur, les registres des fenêtres situées au-dessus du niveau d'imbrication d'appel le plus profond ne sont jamais accessibles du tout, ils sont donc complètement gaspillés. C'est le travail de Stanford sur les compilateurs qui les a conduits à ignorer le concept de fenêtre de registre, pensant qu'un compilateur efficace pourrait faire un meilleur usage des registres qu'un système fixe dans le matériel. (Le même raisonnement s'appliquerait à un programmeur intelligent en langage assembleur.)
RISC I

La première tentative de mise en œuvre du concept RISC s'appelait à l'origine Gold . Les travaux sur la conception ont commencé en 1980 dans le cadre d'un cours de conception VLSI, mais la conception alors compliquée a fait planter presque tous les outils de conception existants. L'équipe a dû passer beaucoup de temps à améliorer ou à réécrire les outils, et même avec ces nouveaux outils, il a fallu un peu moins d'une heure pour extraire la conception sur un VAX-11/780 .
La conception finale, appelée RISC I , a été publiée dans le Symposium international sur l'architecture informatique (ISCA) de l'Association for Computing Machinery (ACM ) en 1981. Elle comportait 44 500 transistors mettant en œuvre 31 instructions et un fichier de registres contenant 78 registres 32 bits. Cela permettait d'avoir six fenêtres de registres contenant 14 registres. Sur ces 14 registres, 4 se chevauchaient par rapport à la fenêtre précédente. Le total est alors de : 10*6 registres dans les fenêtres + 18 globaux = 78 registres au total. La section de contrôle et de décodage des instructions n'occupait que 6 % de la matrice, alors que la conception typique de l'époque en utilisait environ 50 % pour le même rôle. Le fichier de registres occupait la majeure partie de cet espace.
RISC I proposait également un pipeline d'instructions en deux étapes pour une vitesse supplémentaire, mais sans la réorganisation complexe des instructions des conceptions plus modernes. Cela rend les branches conditionnelles problématiques, car le compilateur doit remplir l'instruction suivant une branche conditionnelle (le soi-disant emplacement de délai de branchement ), avec quelque chose sélectionné comme étant « sûr » (c'est-à-dire ne dépendant pas du résultat de la condition). Parfois, la seule instruction appropriée dans ce cas est NOP. Un nombre notable de conceptions ultérieures de style RISC nécessitent toujours la prise en compte du délai de branchement.
Après un mois de validation et de débogage, la conception fut envoyée au service innovant MOSIS pour la production le 22 juin 1981, en utilisant un procédé de 2 μm (2 000 nm). Divers retards les forcèrent à abandonner leurs masques à quatre reprises, et les plaquettes avec des exemples fonctionnels ne revinrent à Berkeley qu'en mai 1982. Le premier « ordinateur » RISC I fonctionnel (en fait une carte de contrôle) fonctionna le 11 juin. Lors des tests, les puces se révélèrent moins performantes que prévu. En général, une instruction prenait 2 μs pour s'exécuter, alors que la conception originale prévoyait environ 0,4 μs (cinq fois plus vite). Les raisons précises de ce problème n'ont jamais été entièrement expliquées. Cependant, tout au long des tests, il est apparu clairement que certaines instructions s'exécutaient à la vitesse prévue, ce qui suggère que le problème était physique et non logique.
Si la conception avait fonctionné à pleine vitesse, les performances auraient été excellentes. Des simulations utilisant une variété de petits programmes ont clairement montré que le RISC I à 4 MHz était plus rapide que le VAX 11/780 à 5 MHz à 32 bits et le Zilog Z8000 à 5 MHz à 16 bits . La taille du programme était environ 30 % plus grande que celle du VAX mais très proche de celle du Z8000, ce qui valide l'argument selon lequel la densité de code plus élevée des conceptions CISC n'était pas si impressionnante en réalité. En termes de performances globales, le RISC I était deux fois plus rapide que le VAX et environ quatre fois plus rapide que le Z8000. Les programmes ont fini par effectuer à peu près le même nombre total d'accès à la mémoire car le fichier de registres volumineux améliorait considérablement les chances que l'opérande nécessaire soit déjà sur la puce.
Il est important de replacer ces performances dans leur contexte. Même si la conception RISC était plus lente que celle du VAX, cela ne changeait rien à l'importance de la conception. Le RISC permettait la production d'un véritable processeur 32 bits sur une puce réelle en utilisant ce qui était déjà une ancienne usine. Les conceptions traditionnelles ne pouvaient tout simplement pas le faire ; avec une si grande partie de la surface de la puce dédiée à la logique du décodeur, une véritable conception 32 bits comme le Motorola 68020 nécessitait des usines plus récentes avant de devenir pratique. En utilisant les mêmes usines, le RISC I aurait pu largement surpasser la concurrence.
Le 12 février 2015, l'IEEE a installé une plaque à l'Université de Californie à Berkeley pour commémorer la contribution du RISC-I. La plaque dit :
- Les étudiants de l'Université de Californie à Berkeley ont conçu et construit le premier ordinateur VLSI à jeu d'instructions réduit en 1981. Les instructions simplifiées de RISC-I ont réduit le matériel nécessaire au décodage et au contrôle des instructions, ce qui a permis d'obtenir un espace d'adressage plat de 32 bits, un grand nombre de registres et une exécution en pipeline. S'adaptant bien aux programmes C et au système d'exploitation Unix, RISC-I a influencé les jeux d'instructions largement utilisés aujourd'hui, notamment ceux des consoles de jeux, des smartphones et des tablettes.
RISC II

Alors que la conception du RISC I prenait du retard, les travaux à Berkeley s'étaient déjà tournés vers le nouveau design Blue . Les travaux sur Blue ont progressé plus lentement que sur Gold, à la fois en raison de l'absence de besoin urgent maintenant que Gold allait être fabriqué, et des changements dans les classes et les étudiants qui encadraient l'effort. Ce rythme leur a également permis d'ajouter plusieurs nouvelles fonctionnalités qui finiraient par améliorer considérablement la conception.
La principale différence résidait dans la simplicité des circuits de cache qui éliminaient une ligne par bit (de trois à deux), réduisant ainsi considérablement la taille du fichier de registre. Ce changement nécessitait également une synchronisation de bus beaucoup plus serrée, mais c'était un petit prix à payer et, pour répondre aux besoins, plusieurs autres parties de la conception ont également été accélérées.
Les économies réalisées grâce à la nouvelle conception ont été considérables. Alors que Gold contenait un total de 78 registres dans 6 fenêtres, Blue contenait 138 registres divisés en 8 fenêtres de 16 registres chacune, avec 10 autres globaux. Cette extension du fichier de registres augmente les chances qu'une procédure donnée puisse contenir tout son stockage local dans des registres et augmente la profondeur d'imbrication. Néanmoins, le fichier de registres plus grand nécessitait moins de transistors et la conception finale de Blue, fabriquée sous le nom de RISC II , implémentait l'ensemble du jeu d'instructions RISC avec seulement 40 760 transistors.
L'autre changement majeur a été d'inclure un extenseur de format d'instruction , qui "convertissait" de manière invisible les instructions 16 bits en un format 32 bits. Cela permettait de stocker des instructions plus petites, généralement des éléments avec un ou aucun opérande, comme NOP, en mémoire dans un format 16 bits plus petit, et de regrouper deux de ces instructions dans un seul mot machine. Les instructions seraient étendues de manière invisible vers des versions 32 bits avant d'atteindre l' unité arithmétique et logique (ALU), ce qui signifie qu'aucun changement n'était nécessaire dans la logique de base. Cette technique simple a donné lieu à une amélioration surprenante de 30 % de la densité du code, ce qui permettait à un programme par ailleurs identique sur Blue de s'exécuter plus rapidement que sur Gold en raison du nombre réduit d'accès à la mémoire.
Le RISC II s'est révélé beaucoup plus performant sur silicium et a surpassé presque tous les mini-ordinateurs dans presque toutes les tâches lors des tests. Par exemple, les performances allaient de 85 % de la vitesse du VAX à 256 % sur diverses charges. Le RISC II a également été comparé au célèbre Motorola 68000 , alors considéré comme la meilleure implémentation de puce commerciale, et l'a surpassé de 140 % à 420 %.
Suite à donner
Les travaux sur les conceptions RISC originales ont pris fin avec RISC II, mais le concept a survécu à Berkeley. Le noyau de base a été réutilisé dans SOAR en 1984, essentiellement un RISC converti pour exécuter Smalltalk (de la même manière qu'on pouvait prétendre que RISC exécutait C ), et plus tard dans le VLSI-BAM similaire qui exécutait Prolog au lieu de Smalltalk. Un autre effort a été SPUR , qui était un ensemble complet de puces nécessaires pour construire une station de travail 32 bits complète .
Le RISC est moins connu, mais plus influent, pour avoir été à la base de la conception commerciale du processeur SPARC de Sun Microsystems . C'est le SPARC qui a clairement démontré pour la première fois la puissance du concept RISC ; lorsqu'ils ont été livrés dans les premiers Sun-4, ils ont surpassé tout ce qui se trouvait sur le marché. Cela a conduit pratiquement tous les fournisseurs d'Unix à se précipiter pour créer leur propre conception RISC, ce qui a donné lieu à des conceptions telles que le DEC Alpha et le PA-RISC , tandis que Silicon Graphics (SGI) a acheté MIPS Computer Systems . En 1986, la plupart des grands fournisseurs de puces ont suivi, travaillant sur des projets tels que le Motorola 88000 , le Fairchild Clipper , l'AMD 29000 et le PowerPC . Le 13 février 2015, l'IEEE a installé une plaque chez Oracle Corporation à Santa Clara. On peut y lire :
- Sun Microsystems a lancé l'architecture de processeur évolutif SPARC (Scalable Processor Architecture) RISC en 1987. S'appuyant sur les développements de RISC de l'Université de Californie à Berkeley et des compilateurs et systèmes d'exploitation de Sun, l'architecture SPARC était hautement adaptable à l'évolution des semi-conducteurs, des logiciels et des technologies des systèmes, ainsi qu'aux besoins des utilisateurs. L'architecture offrait les stations de travail et les serveurs les plus performants et évolutifs, pour les utilisations d'ingénierie, d'entreprise, d'Internet et de cloud computing.
Les techniques développées pour et parallèlement à l'idée du jeu d'instructions réduit ont également été adoptées dans des implémentations et extensions successivement plus puissantes de l' architecture x86 « complexe » traditionnelle . Une grande partie du nombre de transistors d'un microprocesseur moderne est consacrée aux caches volumineux, aux nombreux étages de pipeline , à la répartition des instructions superscalaires , à la prédiction de branchement et à d'autres techniques modernes qui sont applicables quelle que soit l'architecture d'instruction. La quantité de silicium dédiée au décodage des instructions sur une implémentation x86 moderne est proportionnellement assez faible, de sorte que la distinction entre les implémentations de processeurs « complexes » et RISC est devenue floue.