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.
la source
Réponses:
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 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)
la source
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.
la source
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.
la source
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!
la source
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, ecx
sur les processeurs Intel décodent en 3 uops ( pourquoi? ), et notre meilleure estimation est que ce sont des uops de type MOV qui le fonttmp = 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 desmov
instructions 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.
la source
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.
la source
SHL r/m32, cl
a 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.)