Après un édito très introspectif, je reviens à un sujet qui concerne bien entendu nos vieilles machines mais qui me tient aussi à cœur – ne voyez toutefois rien de personnel dans son titre… Comment vouliez-vous que j’attire l’attention sur un article de vulgarisation consacré au fonctionnement des processeurs ? D’ailleurs, je l’ai mis aussi dans la catégorie « technologie » du site à l’instar de notre dernière chronique qui l’a en grande partie motivé. En effet, il règne encore une certaine incompréhension autour de la puissance des machines ; certes les consoles qui arrivent en fin d’année se battent plutôt à coups de téraflops – et pour cause, ce sont toutes deux des machines 64-bit – mais il s’agit au fond de l’actualisation d’une « guerre » un peu vaine entre joueurs… Il faut dire qu’il est plus facile de comparer des chiffres que des architectures complexes et, en outre, les processeurs ont eu tendance à « doubler leurs bits » à chaque génération durant les deux dernières décennies du vingtième siècle. Ce concours de bits un peu puéril s’est toutefois pas mal calmé au mitan des années 1990, lorsqu’il est devenu évident que la Jaguar, et même la Nintendo 64, n’écrasaient pas tant que ça la concurrence. La première, avec sa célèbre campagne publicitaire « Do The Math » (« faites le calcul »), constitue même l’exemple parfait du raisonnement discutable en matière de bits. La console d’Atari contient certes des composants 64-bit, mais on ne peut pas la qualifier pour autant de 64-bit comme il serait tout aussi réducteur d’en faire une simple 16-bit à cause de son CPU… Mais de quoi parle-t-on précisément ici ?
Important!
Avertissement : Je ne suis hélas pas un spécialiste en électronique, mais je reste titulaire du diplôme d’une école d’ingénieur en informatique où j’ai étudié l’architecture, wrappé un processeur 8-bit et appris des rudiments d’assembleur (dans le manuel du 68000). Il y aura sans doute des imprécisions, mais ce serait bien que les intégristes comprennent qu’il est parfois difficile, voire impossible, d’être clair, agréable à lire et rigoureux à la fois. Merci.
Coucou, tu veux voir mes bits ?
Le numérique, ou digital pour employer un anglicisme incorrect, repose sur la représentation de données avec des chiffres et, dans la pratique en binaire, uniquement avec des 0 et des 1. Pourquoi ? Parce que si l’on prend l’exemple d’un support analogique comme un vinyle, sa surface peut s’abîmer et altérer le son qu’il émet au contact de la tête du lecture. Un CD aussi, mais l’écart entre un « trou » (0) et une « bosse » (1) est suffisamment « grand » pour qu’une érosion légère ne modifie pas les données. Et c’est le même principe à l’œuvre dans les ordinateurs où 1 et 0 correspondant à des tensions électriques assez différentes pour ne pas se tromper. L’inconvénient, c’est que les données prennent forcément beaucoup plus de place. Avec un seul bit, on ne code que deux valeurs possibles au lieu de dix avec le système décimal. Il en faut deux pour quatre valeurs (00=0, 01=1, 10=2, 11=3), et huit bits (ce qu’on appelle un octet (*)) pour 256 valeurs. Pour alléger la notation, les octets sont souvent représentés en hexadécimal. Comme un caractère de ce système peut prendre seize valeurs entre 0 et 9 puis A à F, un octet peut s’écrire à l’aide de deux caractères hexadécimaux. Et tout cela permet donc de chiffrer des données très différentes : la valeur d’une variable dans un calcul, le caractère d’un texte, une adresse dans la mémoire de la machine, mais aussi les instructions qui vont les manipuler – le langage machine. Aussi appelé assembleur dans une forme lisible par un humain, il est composé d’instructions qui occupent, selon leur complexité, une ou plusieurs lignes elles-mêmes plus ou moins « longues » selon le type de processeur. Et c’est justement le nombre de bits qui va définir cette longueur !
Important!
(*) : Un octet est appelé « byte » en anglais, ce qui crée bon nombre de confusions. On est censé noter par exemple « Mb » pour des mégabits et « MB » pour des mégaoctets mais, dans la pratique, beaucoup de monde ne respecte pas cette convention malheureusement…
La puissance réside-t-elle dans la richesse du langage ?
Si en novembre 1971, le premier microprocesseur commercialisé, le 4004 d’Intel, est 4-bit, il est suivi seulement six mois plus tard, en avril 1972, par le 8008 qui gère des données de 8 bits. Les premiers micro-ordinateurs domestiques, et a fortiori les premières consoles, étaient donc tous architecturés autour de processeurs 8-bit, les plus répandus étant le 6502 de MOS (et ses dérivés) et le Z80 de Zilog. Ainsi, ils traitent les données d’un octet à chaque cycle, comme s’ils lisaient des lignes de huit caractères une par une. Donc, même si cela ne préjuge pas de la vitesse à laquelle ils les lisent (cf. section suivante), le fait de lire 8 bits à la fois plutôt que quatre ou seize a bien un impact sur ses performances. Car plus les données sont « grandes », plus elles peuvent être complexes. Ainsi, un CPU 16-bit peut notamment gérer des variables codées sur deux fois plus de bits, et donc ayant bien plus de valeurs possibles – pas seulement le double, mais 65 536 valeurs contre 256 ! Cela permet par exemple de ne pas se cantonner aux nombres entiers, mais manipuler des réels (avec des chiffres après la virgule), très utiles dans les calculs complexes de moteurs physiques ou pour la 3D. Surtout que lorsque l’on modifie une variable 8-bit, il y a risque de dépassement car sa valeur repasse à zero au-delà de 255 – c’est d’ailleurs la raison du fameux bug du niveau 256 de Pac-Man (1980). Cela dit, un CPU 8-bit pourra tout de même manipuler des données de 16 bits, mais devra les faire « tenir » sur deux lignes en mémoire, ou deux registres 8-bit. Il sera donc deux fois plus « lent » qu’un processeur 16-bit, du moins à fréquence égale.
De la même manière, lire le double de bits permettra de manipuler des adresses en mémoire plus longues, et donc des quantités de mémoire plus grandes, ce que ce soit en RAM ou en ROM dans une cartouche ou autre support de stockage. C’est ce qui explique aussi, même si le prix des composants a davantage joué, l’augmentation de la taille des jeux à chaque génération… Et c’est enfin vrai pour les instructions elles-mêmes. Prenons deux cas de figure pour un CPU 8-bit, lisant donc les données octet par octet. On peut tout d’abord imaginer qu’une instruction tienne sur un octet entier, ce qui permet d’avoir 256 commandes possibles. Mais celles-ci fonctionnent rarement sans au moins un « argument » (une variable manipulée par l’instruction, comme un nombre faisant partie d’un calcul), et ce dernier devra forcément être placé à la ligne suivante – et nécessitera donc un second cycle pour être lu… Cependant, on peut à présent imaginer les choses différemment, avec une instruction codée sur les quatre premiers bits de l’octet, et l’argument (s’il n’y en a qu’un seul bien sûr) sur les quatre autres. Le CPU peut donc lire la commande en un seul cycle mais on ne peut définir de cette manière que seize instructions différentes, et ne manipuler que des valeurs de 0 à 15. Ces exemples sont toutefois (volontairement) caricaturaux car, dans la pratique, l’assembleur propose les deux types d’instructions, voire des commandes « hybrides » avec un argument sur une partie de la première ligne, et un autre plus « gros » sur la suivante.
Dans le milieu de la vidéo ci-dessus que l’on avait relayé il y a trois ans, notre membre d’honneur Daniel Macré explique quelques optimisations employées pour Vroom (1991), comme l’utilisation de « décalages » – décaler les bits d’une donnée vers la gauche ou la droite permet de multiplier et diviser par deux – bien plus rapides que de vraies divisions. Dans une autre partie de cette interview (filmée par votre serviteur en 2007) qui n’a pas été conservée dans ce documentaire, Daniel explique aussi qu’il utilisait uniquement l’instruction Jump, qui « saute » dans le programme d’un nombre de lignes donné, plutôt que Branch qui envoie à une adresse précise. Cette dernière est forcément plus longue puisque, et là c’est présent dans la vidéo ci-dessus, l’Atari ST peut gérer des adresses sur 32 bits, donc occupant (a priori) deux cycles de son CPU 16-bit (un 68000) sans compter l’instruction elle-même… C’est aussi sur ce principe que sont apparus les microprocesseurs RISC (« à jeu d’instructions réduit ») dont le 6502 est considéré comme un précurseur. Contrairement aux CISC, ils utilisent comme leur nom l’indique moins d’instructions, mais ils sont donc du coup bien plus rapides. Mais cette distinction a perdu de sa pertinence avec le Pentium Pro et son architecture RISC qui émule du CISC. Sans compter qu’il y a aussi des processeurs multi-cœurs mais, avant ça, il nous faut aborder la question de la fréquence…
Parler vite ou parler bien
La fréquence d’horloge est en effet l’autre paramètre qui va définir la vitesse d’un processeur et donc, a fortiori, de la machine qui en est équipée… Exprimée en Hertz comme toutes les fréquences, c’est-à-dire en nombre de fois par seconde (s-1 pour les matheux), elle définit dans le cas d’un processeur le nombre de cycles qu’il effectue à chaque seconde (trois milliards par seconde pour un CPU à 3 GHz – oui, c’est rapide). C’est donc loin d’être anodin, car si un processeur 8-bit ne traite qu’un octet par cycle au lieu de deux d’un coup, il peut dans la pratique lire autant de données qu’un 16-bit s’il est cadencé deux fois plus rapidement. Or, au hasard, le CPU 8-bit de la PC Engine est cadencé à 7,16 MHz, soit pile le double du CPU 16-bit de la Super Nintendo, à 3,58 MHz ! C’est en partie ce qui explique d’ailleurs que la console de NEC soit plus rapide que celle de Nintendo, comme on l’avait déjà noté dans cet édito, mais la réalité est bien sûr plus complexe. Leurs processeurs centraux traitent juste autant de données par seconde mais, si vous avez suivi, un CPU 16-bit peut gérer des données et des instructions plus complexes. Pour des jeux d’arcade sans moteur physique, fausse 3D ou collision complexe (au hasard un shoot ’em up), la PC Engine n’était clairement pas désavantagée, donc, mais l’architecture d’une console ne se limite pas à son processeur central. Et c’est là que ça devient beaucoup plus compliqué…
Tout d’abord, pour rester sur notre exemple, si l’on considère la PC Engine comme une console 8-bit à cause de son CPU, c’est clairement réducteur puisqu’elle dispose non pas d’un seul mais de deux processeurs graphiques 16-bit, contre un seul (baptisé PPU) pour la Super Nintendo. Les graphismes ayant une part importante dans les jeux vidéo, il n’est donc pas idiot de la rattacher à la génération 16-bit de la Mega Drive et de sa rivale de Nintendo, puisqu’elle en est bien plus proche dans les faits. Et il y a encore de nombreux autres paramètres qui entrent dans les performances d’une machine. Le cas de la Super Nintendo est abordé dans l’épisode de Very Hard ci-dessus mais Byuu, l’auteur de son émulateur bsnes, explique dans notre dernière chronique pourquoi il faut idéalement un processeur à 3 GHz pour reproduire de manière très fidèle le fonctionnement de la console. Il compare le déroulement d’un jeu à une chaîne de montage, car le CPU n’interagit pas seulement avec le GPU, mais aussi avec plein d’autres composants. Le fameux bus, chargé de transmettre les données entre eux, est d’ailleurs crucial et explique en grande partie pourquoi la Jaguar n’est pas à la hauteur de ses prétentions. Ses deux processeurs Tom et Jerry contiennent chacun un RISC 32-bit, et le premier inclut même un processeur objet et un blitter tous deux 64-bit, mais il est quasi-impossible de synchroniser convenablement tout ce petit monde, en particulier quand le « chef d’orchestre » est un bon vieux 16-bit, le Motorola 68000.
Important!
Je vous recommande à ce sujet les échanges sur les forums de yAronet concernant le récent homebrew Tube 2020 sur Jaguar, en particulier les explications de Zerosquare confirmées et enrichies ensuite par celles de son développeur, Thibault Bernard alias DrTypo.
Théoriquement, Tom et Jerry n’avaient pas forcément à passer par lui ayant un accès direct à la RAM mais, dans la pratique, il y avait encore beaucoup de jeux 2D à l’époque et la majorité des développeurs se sont contentés de porter des jeux 16-bit dessus. Encore aujourd’hui, c’est ce qui permet à Lawrence « Cyrano Jones » Staveley de réaliser des « portages » de jeux Atari ST comme Star Wars: The Empire Strikes Back, qui tiennent quasiment de l’émulation optimisée – le micro-ordinateur étant conçu autour du même processeur – mais ne sont pas aussi simples et rapides à faire qu’on pourrait le penser… L’éternel débat de savoir si la Jaguar aurait pu faire mieux si ceci ou cela est relancé régulièrement sur les forums, et il serait peut-être temps de se faire une raison. Bourrer sa console de processeurs surpuissants ne sert à rien si l’architecture qui les lie n’est pas suffisamment bien conçue ; ce serait comme assembler les pièces d’un tank avec du scotch. Même aujourd’hui où les CPU demeurent 64-bit mais disposent de plusieurs cœurs, ces derniers ne peuvent pas forcément travailler correctement en parallèle si les systèmes d’exploitation ou les programmes n’ont pas été pensés pour ça. Cela marche bien pour lancer plusieurs applications sans lien entre elles mais, au sein d’un programme donné comme un jeu, il faut bien que le cœur en charge des collisions attende celui qui définit la position des objets…
C’est sans doute un exemple idiot, mais vous comprenez le principe. Autrement dit, si déterminer la puissance (ou du moins la « génération ») d’une console sur son type de CPU était pertinent dans les années 1970 et durant une bonne partie des années 1980, alors que les consoles avaient une architecture assez simple, cela a perdu son sens bien avant que les équipes marketing n’arrêtent de le faire… Le CPU VR4300 de la Nintendo 64 avait beau disposer de capacités de calcul le rapprochant d’un 64-bit, elles ont rarement été exploitées d’autant que son bus, là encore, était 32-bit. Et il en est de même pour la Dreamcast, qualifiée de « 128-bit » en son temps. Son GPU PowerVR2 est 64-bit a priori, mais son CPU SH-4 est en fait un RISC 32-bit – le Pentium n’est passé de 32 à 64 bits qu’en l’an 2000 avec le Pentium 4 après tout. Le SH-4 est toutefois doté d’une unité de calcul (FPU) spécialisée dans la manipulation de nombres « à virgules flottantes » (les réels) et donc pour la 3D, qui est bien 128-bit. De même, le fameux « Emotion Engine » de la PlayStation 2 était 64-bit mais stockait ses données dans des registres 128-bit. Et il faut bien comprendre que même aujourd’hui, il n’existe pas de processeur 128-bit dans l’informatique domestique. En revanche, la plupart des GPU utilisent par exemple des bus 128-bit pour transférer les données plus rapidement… Après tout, il n’y a pas besoin de millions d’instructions différentes, et puis il y a les limites physiques. On voit d’ailleurs bien, avec l’essor du SSD et la PS5, que la « guerre » se joue désormais de plus en plus sur la vitesse de transfert entre composants.
La fameuse vidéo du 13 mai présentant l’Unreal Engine 5 est d’ailleurs très intéressante à ce sujet. Alors que tout le monde parlait de ray tracing, cette vidéo n’en utilise pas (même si elle emploie un autre système d’éclairage global et dynamique) et se focalise sur une technologie ingénieuse baptisée Nanite. Celle-ci repose sur l’idée toute bête (avec le recul) qu’il ne sert à rien d’afficher plus de polygones qu’il n’y a de pixels à l’écran ! Ainsi, non seulement le débat du nombre de bits est caduc, mais celui du nombre de polygones affiché, très important sur la génération PlayStation 2, Xbox et GameCube, a pris aussi un sacré coup de vieux… Cela m’a d’ailleurs rappelé l’excellent portage Saturn de SEGA Rally (1994), pour lequel les développeurs avaient eu l’idée de ne pas calculer les polygones de la voiture situés de l’autre côté de la caméra – pas besoin d’afficher ce que le joueur ne voit pas ! Et donc, de manière générale, la puissance de calcul d’une machine n’a pas tant d’intérêt si l’homme qui la programme ne sait pas en tirer parti…