Pourquoi Intel cache-t-il le cœur RISC interne dans ses processeurs?

89

En commençant par Pentium Pro (microarchitecture P6), Intel a repensé ses microprocesseurs et utilisé le cœur RISC interne selon les anciennes instructions CISC. Depuis Pentium Pro, toutes les instructions CISC sont divisées en parties plus petites (uops) puis exécutées par le noyau RISC.

Au début, il était clair pour moi qu'Intel avait décidé de cacher la nouvelle architecture interne et de forcer les programmeurs à utiliser le "shell CISC". Grâce à cette décision, Intel pourrait entièrement repenser l'architecture des microprocesseurs sans rompre la compatibilité, c'est raisonnable.

Cependant, je ne comprends pas une chose, pourquoi Intel garde toujours un jeu d'instructions RISC interne caché pendant tant d'années? Pourquoi ne laisseraient-ils pas les programmeurs utiliser les instructions RISC comme les anciennes instructions x86 CISC?

Si Intel maintient la compatibilité descendante pendant si longtemps (nous avons toujours le mode virtuel 8086 à côté du mode 64 bits), pourquoi ne nous permettent-ils pas de compiler des programmes afin qu'ils contournent les instructions CISC et utilisent directement le noyau RISC? Cela ouvrira un moyen naturel d'abandonner lentement le jeu d'instructions x86, qui est obsolète de nos jours (c'est la principale raison pour laquelle Intel a décidé d'utiliser le cœur RISC à l'intérieur, n'est-ce pas?).

En regardant la nouvelle série Intel 'Core i', je vois qu'ils étendent uniquement les instructions CISC en ajoutant AVX, SSE4 et autres.

Goofy
la source
1
notez qu'il existe certains processeurs x86 où le jeu d'instructions RISC interne est exposé
phuclv

Réponses:

90

Non, le jeu d'instructions x86 n'est certainement pas obsolète. C'est plus populaire que jamais. La raison pour laquelle Intel utilise un ensemble de micro-instructions de type RISC en interne est qu'elles peuvent être traitées plus efficacement.

Ainsi, un processeur x86 fonctionne en ayant un décodeur assez robuste dans le frontend, qui accepte les instructions x86, et les convertit en un format interne optimisé, que le backend peut traiter.

Quant à exposer ce format à des programmes «externes», il y a deux points:

  • ce n'est pas un format stable. Intel peut le changer entre les modèles de CPU pour s'adapter au mieux à l'architecture spécifique. Cela leur permet de maximiser l'efficacité, et cet avantage serait perdu s'ils devaient se contenter d'un format d'instruction fixe et stable pour un usage interne ainsi qu'un usage externe.
  • il n'y a rien à gagner à le faire. Avec les processeurs énormes et complexes d'aujourd'hui, le décodeur est une partie relativement petite du processeur. Le fait de devoir décoder des instructions x86 rend cela plus complexe, mais le reste du processeur n'est pas affecté, donc dans l'ensemble, il n'y a que très peu à gagner, en particulier parce que le frontend x86 devrait toujours être là, afin d'exécuter du code «hérité» . Ainsi, vous ne sauveriez même pas les transistors actuellement utilisés sur le frontend x86.

Ce n'est pas tout à fait un arrangement parfait, mais le coût est assez faible et c'est un bien meilleur choix que de concevoir le processeur pour prendre en charge deux jeux d'instructions complètement différents. (Dans ce cas, ils finiraient probablement par inventer un troisième ensemble de micro-opérations à usage interne, simplement parce que ceux-ci peuvent être modifiés librement pour s'adapter au mieux à l'architecture interne du processeur)

jalf
la source
1
Bons points. RISC est une bonne architecture de base, où BON signifie s'exécute rapidement et peut être implémenté correctement, et l'ISA x86, qui a une histoire architecturale CISC, n'est que maintenant, une disposition de jeu d'instructions avec une énorme histoire et une fabuleuse richesse de logiciels binaires disponibles pour cela. , en plus d'être efficace pour le stockage et le traitement. Ce n'est pas un shell CISC, c'est la norme ISA de facto de l'industrie.
Warren P
2
@Warren: sur la dernière partie, je ne pense pas. Un jeu d'instructions CISC bien conçu est plus efficace en termes de stockage, oui, mais d'après les quelques tests que j'ai vus, l'instruction x86 «moyenne» mesure environ 4,3 octets de largeur, ce qui est plus que ce qu'elle serait généralement une architecture RISC. x86 perd beaucoup d'efficacité de stockage car il a été conçu et étendu au hasard au fil des ans. Mais comme vous le dites, sa principale force est l'histoire et l'énorme quantité de code binaire existant.
jalf
1
Je n'ai pas dit que c'était «l'ICCA bien conçu», juste «une histoire énorme». Les bonnes pièces sont les pièces de conception de puces RISC.
Warren P
2
@jalf - D'après l'inspection des binaires réels, la taille des instructions dans x86 est d'environ 3 octets chacun en moyenne. Il y a bien sûr des instructions beaucoup plus longues, mais les plus petites ont tendance à dominer dans l'utilisation réelle.
srking le
1
La longueur moyenne des instructions n'est pas une bonne mesure de la densité du code: le type le plus courant d'instruction x86 dans un code typique est le chargement et le stockage (il suffit de déplacer les données vers l'endroit où elles peuvent être traitées, puis de les remettre en mémoire, les processeurs RISC et environ la moitié des CISC ont beaucoup de registres, donc pas besoin de faire autant. Aussi combien une instruction peut faire (les instructions d'armement peuvent faire environ 3 choses).
ctrl-alt-delor
20

La vraie réponse est simple.

Le principal facteur derrière la mise en œuvre des processeurs RISC était de réduire la complexité et de gagner en vitesse. L'inconvénient de RISC est la densité d'instructions réduite, ce qui signifie que le même code exprimé au format RISC a besoin de plus d'instructions que le code CISC équivalent.

Cet effet secondaire ne signifie pas grand-chose si votre CPU fonctionne à la même vitesse que la mémoire, ou du moins si les deux fonctionnent à des vitesses raisonnablement similaires.

Actuellement, la vitesse de la mémoire par rapport à la vitesse du processeur montre une grande différence d'horloges. Les processeurs actuels sont parfois cinq fois ou plus rapides que la mémoire principale.

Cet état de la technologie favorise un code plus dense, ce que fournit le SCRC.

Vous pouvez affirmer que les caches pourraient accélérer les processeurs RISC. Mais on peut dire la même chose des processeurs CISC.

Vous obtenez une plus grande amélioration de la vitesse en utilisant CISC et caches que RISC et caches, car la même taille de cache a plus d'effet sur le code haute densité fourni par CISC.

Un autre effet secondaire est que RISC est plus difficile sur l'implémentation du compilateur. Il est plus facile d'optimiser les compilateurs pour les processeurs CISC. etc.

Intel sait ce qu'il fait.

C'est tellement vrai que ARM a un mode de densité de code plus élevé appelé Thumb.

Jorge Aldo
la source
1
De plus, un noyau RISC interne réduit le nombre de transistors sur un processeur CISC. Au lieu de câbler en dur chaque instruction CISC, vous pouvez utiliser un microcode pour les exécuter. Cela conduit à la réutilisation des instructions de microcode RISC pour différentes instructions CISC, utilisant ainsi moins de surface de puce.
Sil
16

Si Intel maintient la rétrocompatibilité pendant si longtemps (nous avons toujours le mode virtuel 8086 à côté du mode 64 bits), pourquoi ne nous permettent-ils pas de compiler des programmes afin qu'ils contournent les instructions CISC et utilisent directement le noyau RISC? Cela ouvrira un moyen naturel d'abandonner lentement le jeu d'instructions x86, qui est obsolète de nos jours (c'est la principale raison pour laquelle Intel a décidé d'utiliser le cœur RISC à l'intérieur, n'est-ce pas?).

Vous devez examiner l'angle commercial de cela. Intel a en fait essayé de s'éloigner de x86, mais c'est l'oie qui pond des œufs d'or pour l'entreprise. XScale et Itanium n'ont jamais atteint le niveau de succès de leur cœur de métier x86.

Ce que vous demandez essentiellement, c'est qu'Intel se fende les poignets en échange de flous chauds de la part des développeurs. Saper x86 n'est pas dans leur intérêt. Tout ce qui fait que plus de développeurs n'ont pas à choisir de cibler x86 sape x86. Cela, à son tour, les sape.

Mike Thomsen
la source
6
Oui, quand Intel a essayé de le faire (Itanium), le marché a simplement répondu par un haussement d'épaules.
Warren P
Il convient de noter qu'il y avait une variété de facteurs lors de l'échec d'Itanium, et pas seulement parce qu'il s'agissait d'une nouvelle architecture. Par exemple, décharger la planification du processeur sur un compilateur qui n'a jamais réellement atteint son objectif. Si l'Itanium était 10x ou 100x plus rapide que les processeurs x86, il se serait vendu comme des petits pains. Mais ce n'était pas plus rapide.
Katastic Voyage
5

La réponse est simple. Intel ne développe pas de processeurs pour les développeurs ! Ils les développent pour les personnes qui prennent les décisions d' achat , ce que fait BTW, c'est ce que fait chaque entreprise dans le monde!

Intel a pris il y a longtemps l'engagement que, (dans des limites raisonnables, bien sûr), leurs processeurs resteraient rétrocompatibles. Les gens veulent savoir que lorsqu'ils achètent un nouvel ordinateur Intel, tous leurs logiciels actuels fonctionneront exactement de la même manière que sur leur ancien ordinateur. (Bien que, espérons-le, plus rapide!)

De plus, Intel sait exactement à quel point cet engagement est important, car ils ont déjà essayé de suivre une voie différente. Combien de personnes connaissez- vous exactement avec un processeur Itanium?!?

Cela ne vous plaira peut-être pas, mais cette décision, de rester avec le x86, est ce qui a fait d'Intel l'un des noms commerciaux les plus reconnaissables au monde!

géo
la source
2
Je ne suis pas d'accord avec l'idée que les processeurs Intel ne sont pas adaptés aux développeurs. Ayant programmé PowerPC et x86 pendant de nombreuses années, j'en suis venu à croire que le CISC est beaucoup plus convivial pour les programmeurs. (Je travaille pour Intel maintenant, mais j'ai pris ma décision sur ce problème avant d'être embauché.)
Jeff
1
@Jeff Ce n'était pas du tout mon intention! La question était de savoir pourquoi Intel n'a-t-il pas ouvert le jeu d'instructions RISC afin que les développeurs puissent l'utiliser. Je n'ai pas dit quoi que ce soit au sujet x86 être amical non-développeur. Ce que j'ai dit, c'est que des décisions comme celle-ci n'étaient pas décidées en pensant aux développeurs , mais étaient plutôt des décisions strictement commerciales.
geo
5

La réponse de @ jalf couvre la plupart des raisons, mais il y a un détail intéressant qu'il ne mentionne pas: le noyau interne de type RISC n'est pas conçu pour exécuter un jeu d'instructions comme ARM / PPC / MIPS. La taxe x86 n'est pas seulement payée dans les décodeurs gourmands en énergie, mais dans une certaine mesure dans tout le noyau. c'est-à-dire que ce n'est pas seulement l'encodage des instructions x86; c'est chaque instruction avec une sémantique étrange.

Supposons qu'Intel ait créé un mode de fonctionnement dans lequel le flux d'instructions était autre chose que x86, avec des instructions plus directement mappées sur uops. Supposons également que chaque modèle de processeur a son propre ISA pour ce mode, afin qu'ils soient toujours libres de changer les éléments internes quand ils le souhaitent, et de les exposer avec une quantité minimale de transistors pour le décodage d'instructions de cet autre format.

Vraisemblablement, vous n'auriez toujours que le même nombre de registres, mappés à l'état architectural x86, de sorte que les systèmes d'exploitation x86 peuvent le sauvegarder / le restaurer sur des commutateurs de contexte sans utiliser le jeu d'instructions spécifique au processeur. Mais si nous supprimons cette limitation pratique, oui, nous pourrions avoir quelques registres supplémentaires car nous pouvons utiliser les registres temporaires cachés normalement réservés au microcode 1 .


Si nous avons juste des décodeurs alternatifs sans modification des étapes ultérieures du pipeline (unités d'exécution), cet ISA aurait encore de nombreuses excentricités x86. Ce ne serait pas une très belle architecture RISC. Aucune instruction ne serait très complexe, mais certaines des autres folies de x86 seraient toujours là.

Par exemple: les décalages gauche / droite laissent l'indicateur de débordement indéfini, à moins que le nombre d'équipes ne soit égal à un, auquel cas OF = la détection de débordement signée habituelle. Folie similaire pour les rotations. Cependant, les instructions RISC exposées pourraient fournir des décalages sans indicateur et ainsi de suite (permettant l'utilisation d'un ou deux des multiples uops qui entrent généralement dans certaines instructions x86 complexes). Donc, cela ne constitue pas vraiment le principal contre-argument.

Si vous comptez créer un tout nouveau décodeur pour un RISC ISA, vous pouvez lui demander de choisir des parties des instructions x86 à exposer en tant qu'instructions RISC. Cela atténue quelque peu la spécialisation x86 du noyau.


Le codage des instructions ne serait probablement pas de taille fixe, car des uops uniques peuvent contenir beaucoup de données. Beaucoup plus de données que cela n'a de sens si toutes les insns sont de la même taille. Un seul uop micro-fusionné peut ajouter un immédiat 32 bits et un opérande mémoire qui utilise un mode d'adressage avec 2 registres et un déplacement 32 bits. (Dans SnB et versions ultérieures, seuls les modes d'adressage à registre unique peuvent micro-fusionner avec les opérations ALU).

Les uops sont très volumineux et pas très similaires aux instructions ARM à largeur fixe. Un jeu d'instructions 32 bits à largeur fixe ne peut charger que des instantanés 16 bits à la fois, de sorte que le chargement d'une adresse 32 bits nécessite une paire charge immédiate faible moitié / charge élevée immédiate. x86 n'a pas à faire cela, ce qui aide à ne pas être terrible avec seulement 15 registres GP limitant la capacité de conserver des constantes dans les registres. (15 est une grande aide sur 7 registres, mais doubler à nouveau à 31 aide beaucoup moins, je pense que certaines simulations ont été trouvées. RSP n'est généralement pas à usage général, donc c'est plus comme 15 registres GP et une pile.)


TL; Résumé DR:

Quoi qu'il en soit, cette réponse se résume à "le jeu d'instructions x86 est probablement le meilleur moyen de programmer un processeur qui doit être capable d'exécuter rapidement des instructions x86", mais nous espérons que cela permet de mieux comprendre les raisons.


Formats uop internes dans le front-end vs le back-end

Voir également Micro fusion et modes d'adressage pour un cas de différences dans ce que les formats uop front-end et back-end peuvent représenter sur les processeurs Intel.

Note de bas de page 1 : Il existe des registres «cachés» à utiliser comme temporaires par microcode. Ces registres sont renommés comme les registres architecturaux x86, de sorte que les instructions multi-uop peuvent s'exécuter dans le désordre.

par exemple xchg eax, ecxsur les processeurs Intel décodent en 3 uops ( pourquoi? ), et notre meilleure estimation est que ce sont des uops de type MOV qui le font tmp = eax; ecx=eax ; eax=tmp;. Dans cet ordre, parce que je mesure la latence de la direction dst-> src à ~ 1 cycle, contre 2 pour l'inverse. Et ces mouvements ne sont pas comme des movinstructions régulières ; ils ne semblent pas être des candidats à l'élimination des mouvements sans latence.

Voir également http://blog.stuffedcow.net/2013/05/measuring-rob-capacity/ pour une mention de la tentative de mesurer expérimentalement la taille du PRF et de la nécessité de tenir compte des registres physiques utilisés pour conserver l'état architectural, y compris les registres cachés.

Dans le front-end après les décodeurs, mais avant l'étape d'émission / de changement de nom qui renomme les registres dans le fichier de registre physique, le format uop interne utilise des numéros de registre similaires aux numéros de reg x86, mais avec de la place pour adresser ces registres cachés.

Le format uop est quelque peu différent à l'intérieur du noyau en désordre (ROB et RS), alias back-end (après l'étape d'émission / de changement de nom). Les fichiers de registre physique int / FP ont chacun 168 entrées dans Haswell , donc chaque champ de registre dans un uop doit être suffisamment large pour en traiter autant.

Puisque le renommage est présent dans le HW, nous ferions probablement mieux de l'utiliser, au lieu de fournir des instructions programmées statiquement directement au back-end. Nous pourrions donc travailler avec un ensemble de registres aussi grand que les registres architecturaux x86 + les temporaires du microcode, pas plus que cela.

Le back-end est conçu pour fonctionner avec un renommage frontal qui évite les risques WAW / WAR, nous ne pouvons donc pas l'utiliser comme un processeur en ordre même si nous le voulions. Il n'a pas de verrouillages pour détecter ces dépendances; qui est géré par problème / renommer.

Cela pourrait être intéressant si nous pouvions alimenter les uops dans le back-end sans le goulot d'étranglement de l'étape de problème / renommer (le point le plus étroit des pipelines Intel modernes, par exemple 4-large sur Skylake contre 4 ALU + 2 ports de chargement + 1 port de stockage dans le back-end). Mais si vous avez fait cela, je ne pense pas que vous puissiez planifier statiquement du code pour éviter la réutilisation des registres et marcher sur un résultat qui est toujours nécessaire si un échec de cache a bloqué une charge pendant une longue période.

Nous avons donc à peu près besoin de fournir des uops à l'étape de problème / renommer, probablement en contournant uniquement le décodage, pas le cache uop ou IDQ. Ensuite, nous obtenons un exécutable OoO normal avec une détection des dangers sensée. La table d'allocation de registres est uniquement conçue pour renommer 16 + quelques registres d'entiers en PRF d'entiers à 168 entrées. Nous ne pouvions pas nous attendre à ce que le matériel renomme un plus grand ensemble de registres logiques sur le même nombre de registres physiques; cela prendrait un RAT plus grand.

Peter Cordes
la source
-3

Pourquoi ne nous permettent-ils pas de compiler des programmes afin qu'ils contournent les instructions du CISC et utilisent directement RISC Core?

En plus des réponses précédentes, l'autre raison est la segmentation du marché. On pense que certaines instructions sont implémentées dans le microcode plutôt que dans le matériel, si bien que permettre à quiconque d'exécuter des micro-opérations arbitraires peut saper les ventes de nouveaux processeurs avec de «nouvelles» instructions CISC plus performantes.

KOLANICH
la source
1
Je ne pense pas que cela ait du sens. Un RISC peut utiliser un microcode, surtout si nous parlons simplement d'ajouter des décodeurs RISC à une interface x86.
Peter Cordes
2
C'est toujours faux. Les nouvelles instructions AES (et les instructions SHA à venir), et d'autres éléments comme PCLMULQDQ ont un matériel dédié. Sur Haswell, AESENC décode en un seul uop ( agner.org/optimize ), donc ce n'est certainement pas du tout microcodé. (Les décodeurs n'ont besoin d'activer le séquenceur ROM du microcode que pour les instructions qui décodent à plus de 4 uops .)
Peter Cordes
1
Vous avez raison de dire que certaines nouvelles instructions utilisent simplement les fonctionnalités existantes d'une manière qui n'est pas disponible avec les instructions x86. Un bon exemple serait BMI2 SHLX , qui vous permet de faire des décalages de nombre de variables sans mettre le décompte dans CL, et sans encourir les uops supplémentaires nécessaires pour gérer la sémantique de l'indicateur x86 merdique (les indicateurs ne sont pas modifiés si le compte de décalage est zéro, donc SHL r/m32, cla une dépendance d'entrée sur FLAGS, et décode à 3 uops sur Skylake. C'était seulement 1 uop sur Core2 / Nehalem, cependant, selon les tests d'Agner Fog.)
Peter Cordes
Merci pour vos commentaires.
KOLANICH