Comment un processeur peut-il fournir plus d'une instruction par cycle?

41

Dans la page Instructions par seconde de Wikipedia, un i7 3630QM délivre environ 110 000 MIPS à une fréquence de 3,2 GHz; ce serait (110 / 3.2 instructions) / 4 core = ~ 8,6 instructions par cycle par core?! Comment un seul noyau peut-il donner plus d'une instruction par cycle?

À ma connaissance, un pipeline ne devrait produire qu'un seul résultat par horloge.

Ce sont mes pensées:

  • La fréquence interne est supérieure à 3,2 GHz
  • Certaines parties de la CPU sont asynchrones, de sorte qu'un humain humble comme moi ne peut pas comprendre
  • Il y a plusieurs pipelines simultanés par cœur
  • Un pipeline peut fournir plus que le résultat par horloge, une instruction peut ignorer des étapes de pipeline et il existe plusieurs pré-analyseurs à suivre
  • Il me manque quelque chose
sans travail
la source
1
Il fournit 110 000 MIPS Dhrystone , donc DMIPS, et non MIPS, est quelque chose que je vois directement - peut-être que cela pourrait faire une différence? Voir en.wikipedia.org/wiki/Dhrystone

Réponses:

44

Premièrement, comme le signalent Keelan et la réponse de Turbo J , la mesure était de 113 093 Dhrystone MIPS non natif .

La microarchitecture Ivy Bridge du i7 3630QM ne peut valider que 4 µops fondus par cycle, bien qu'elle puisse commencer à exécuter 6 µops par cycle. (Le nombre de µops fusionnés dans une trace de code est à peu près égal au nombre d'instructions; certaines instructions complexes sont décodées en plusieurs µops non fusionnés et certaines paires d'instructions peuvent être fusionnées en un seul µop, par exemple, une comparaison immédiate. suivi d'un saut conditionnel.)

Deux de vos spéculations sur la manière dont plusieurs instructions peuvent être exécutées au cours d'un seul cycle sont tout à fait valables et ont été utilisées dans les processeurs actuels. Votre première hypothèse, selon laquelle une horloge interne plus rapide est utilisée, a été utilisée dans les ALU "Fireball" du Pentium 4 d'origine. Ces ALU étaient cadencées à deux fois la fréquence du reste du noyau, qui était déjà relativement élevée.

(Ceci a été réalisé en utilisant une ALU échelonnée dans laquelle la moitié inférieure d'un ajout a été effectuée en un cycle, permettant à une opération dépendante d'utiliser la moitié inférieure du résultat dans le cycle suivant. Pour des opérations comme add, xor ou shift à gauche qui n'a besoin que de la moitié inférieure des opérandes pour produire la moitié inférieure complète du résultat, un tel effet de décalage - également appelé largeur de pipeline - permet une latence de résultat sur un cycle ainsi que le débit d'un cycle.)

HyperSPARC a utilisé une technique quelque peu apparentée, les UAL en cascade. HyperSPARC a introduit les résultats de deux ALU dans une troisième ALU. Cela a permis d'exécuter deux opérations indépendantes et une troisième opération dépendante en un seul cycle.

Votre hypothèse selon laquelle "il existe plusieurs pipelines simultanés par cœur" est l'autre technique utilisée. Ce type de conception est appelé superscalaire et constitue de loin le moyen le plus courant d’augmenter le nombre d’opérations exécutées au cours d’un cycle.

Il existe également quelques autres chances d’exécution des instructions qui méritent d’être signalées. Certaines opérations peuvent être exécutées plus efficacement en dehors des unités d'exécution ordinaires. La technique d'élimination de déplacement exploite l'utilisation du changement de nom de registre dans des processeurs en panne pour effectuer des opérations de déplacement lors du changement de nom de registre; le déplacement copie simplement le numéro de registre physique d'une position dans la table de changement de nom (appelée table d'alias de registre) à une autre. Non seulement cela augmente effectivement la largeur d'exécution, mais cela supprime également une dépendance. Cette technique a été utilisée très tôt avec le x87 basé sur la pile, mais elle est maintenant largement utilisée dans les processeurs x86 hautes performances d'Intel. (L'utilisation d'instructions destructives à deux opérandes dans x86 rend l'élimination des déplacements plus utile que dans un RISC typique.)

Une technique similaire à l'élimination des déplacements est le traitement des instructions de mise à zéro des registres lors du changement de nom. En fournissant un nom de registre qui fournit la valeur zéro, une instruction d'effacement de registre (telle que xor ou soustraction avec les deux opérandes étant le même registre) peut simplement insérer ce nom dans la table de renommage (RAT).

Une autre technique utilisée par certains processeurs x86 réduit le coût des opérations push et pop. Normalement, une instruction utilisant le pointeur de pile devrait attendre un cycle complet pour un push ou un pop précédent pour mettre à jour la valeur du pointeur de pile. En reconnaissant que push et pop ne font qu'ajouter ou soustraire une petite valeur au pointeur de la pile, il est possible de calculer les résultats de plusieurs additions / sous-actions en parallèle. Le délai principal pour l'addition est la propagation de retenue, mais avec des valeurs faibles, les bits les plus significatifs de la valeur de base (dans ce cas, le pointeur de pile) n'auront au plus qu'un report en arrière. Cela permet d'appliquer une optimisation similaire à celle d'un additionneur de retenue de portefeuille à plusieurs additions de petites valeurs. De plus, étant donné que le pointeur de pile est généralement mis à jour uniquement par des constantes,

Il est également possible de fusionner des instructions en une seule opération plus complexe. Alors que le processus inverse consistant à diviser des instructions en plusieurs opérations plus simples est une technique ancienne, la fusion d'instructions (qu'Intel appelle fusion macro-op) peut permettre à la mise en oeuvre de prendre en charge des opérations plus complexes que celles exposées dans le jeu d'instructions.

Sur le plan théorique, d'autres techniques ont été proposées. Les petites constantes autres que zéro peuvent être prises en charge dans la table RAT et certaines opérations simples qui utilisent ou produisent de manière fiable des valeurs aussi petites peuvent être gérées rapidement. ("Physical Register Inlining", Mikko H. Lipasti et al., 2004, a suggéré d'utiliser le RAT comme moyen de réduire le nombre de registres, mais l'idée pourrait être élargie pour prendre en charge le chargement de petites opérations immédiates et simples sur de petits nombres.)

Pour les caches de trace (qui stockent des séquences d'instructions sous des hypothèses particulières de flux de contrôle), il peut être possible de fusionner des opérations séparées par des branches et de supprimer des opérations produisant des résultats inutilisés dans la trace. La mise en cache des optimisations dans un cache de trace peut également encourager la réalisation d’optimisations telles que la fusion d’instructions, ce qui peut ne pas valoir la peine si elles doivent être effectuées à chaque fois que le flux d’instructions est extrait.

La prédiction de valeur peut être utilisée pour augmenter le nombre d'opérations pouvant être exécutées en parallèle en supprimant les dépendances. Un prédicteur de valeur basé sur la foulée est similaire à l'optimisation du pop / push d'un moteur de pile spécialisé mentionné précédemment. Il peut calculer plusieurs ajouts principalement en parallèle, en supprimant la sérialisation. L'idée générale de la prédiction de valeur est qu'avec une valeur prédite, les opérations dépendantes peuvent être exécutées sans délai. (La prédiction de direction et de cible de branche n'est en réalité qu'une forme très limitée de prédiction de valeur, permettant d'extraire les instructions suivantes qui dépendent de la "valeur" de la branche - prise ou non - et de l'adresse d'instruction suivante, une autre valeur.)

Paul A. Clayton
la source
impressionnant! Merci pour ces informations précieuses. Pourriez-vous suggérer un livre où je peux lire toutes ces techniques architecturales?
travail
@workless Une fois que vous avez dépassé les bases du traitement en pipeline et de l'exécution superscalaire hors service (qui seraient couvertes par la plupart des manuels d'architecture informatique), les meilleures sources d'information sont probablement les descriptions de microarchitectures de processeurs spécifiques (comme l'article sur Haswell lié à dans la réponse de gnasher729 ) et des articles universitaires (les conférences ISCA et MICRO ont généralement de bons articles; HPCA, PACT, ASPLOS et peut-être quelques autres ont également une bonne réputation). Andy Glew (peut-être le plus célèbre pour son travail sur le Pentium Pro) ...
Paul A. Clayton
1
... travaillait sur un wiki CompArch, qui présenterait des concepts plus avancés, mais les progrès étaient lents et il a apparemment été piraté il y a quelque temps et ne donne donc maintenant qu'un message d'erreur ( semipublic.comp-arch.net/wiki ). Il a l'intention de rétablir le wiki (le texte original a été préservé) à l'aide de différents logiciels wiki (il a eu quelques problèmes avec le logiciel qu'il utilisait et en profite pour apporter des améliorations), mais "Cela va prendre du temps."
Paul A. Clayton
HyperThreading d’Intel est un bon exemple du succès de l’architecture superscalar. Grâce à toutes ces optimisations, les ingénieurs d’Intel ont découvert qu’environ 30% de l’ALU étaient inutilisés la plupart du temps, car la mémoire ne pouvait pas s’accumuler assez rapidement. le pipeline ne peut pas être rempli suffisamment efficacement. HyperThreading vous permet d'obtenir beaucoup de travail gratuitement dans le scénario idéal. C'est beaucoup moins que d'avoir un nouveau noyau séparé, mais c'est aussi beaucoup moins cher (et il peut aussi être combiné avec un multicœur).
Luaan
@ PaulA.Clayton - deux captures de cette page sont sur Wayback. 20 décembre 2013 et 14 février 2014 . Je ne sais pas si ces captures sont antérieures aux problèmes de la page. Malheureusement, lorsque j'ai essayé de visiter ces pages sur Wayback, j'ai reçu le message " Bummer. La machine qui sert ce fichier est en panne. Nous travaillons dessus. " .
Kevin Fegan
10

Une certaine magie noire se produit à l’intérieur des processeurs modernes, mais vos pensées vont vraiment dans le bon sens.

La clé pour comprendre l'efficacité des processeurs modernes consiste à se rendre compte qu'ils sont superscalaires . De Wikipédia (c'est moi qui souligne):

Une architecture de processeur superscalaire implémente une forme de parallélisme appelée parallélisme au niveau instruction dans un même processeur. Il permet donc un débit de processeur plus rapide que ce qui serait autrement possible à une fréquence d'horloge donnée.

Ces processeurs modernes ont plusieurs unités d'exécution par cœur, comme vous l'avez deviné. L’hyper-threading est intéressant à considérer, certaines parties du pipeline sont dupliquées mais d’autres ne le sont pas.

Une exécution hors service est également intéressante à lire, mais ne répond pas directement à votre question. Il réduit cependant le nombre de cycles de processeur "gaspillés".

L'efficacité est également affectée par de nombreux autres facteurs susceptibles de provoquer un blocage dans le processeur, notamment (sans toutefois s'y limiter):

  • Les résultats des instructions précédentes n'étant pas disponibles.
  • Le cache manque.
  • La branche de code, qui invaliderait les instructions déjà extraites (à lire sur la prédiction de branche ici et ici ).

Les compilateurs modernes essaient d'aider avec beaucoup des éléments ci-dessus, le processeur prend alors le relais. Pour un bon exemple, voir cette question ailleurs sur Stackexchange, qui souligne une différence importante entre deux instructions pouvant faire la même chose (dans certaines circonstances). Cependant, certains peuvent être "plus rapides" que d'autres sur certains processeurs en raison de l'unité d'exécution utilisée.

Pour une explication lisible par l'homme du pipeline de processeurs moderne, voir Parcours du pipeline de processeurs . Pour une explication un peu plus technique, voir le document Microarchitecture d’ Agner Fog .

David
la source
merci pour l'explication et les liens très intéressants. En tant que note, Cell a l’air très intéressant, j’ai hâte d’en apprendre davantage sur les architectures cpu ^ _ ^. "" Le x86 utilise une "superpipeline" comme décrit ci-dessus. La famille Cell utilise une approche "synergique" impliquant neuf mini-processeurs. Il est vrai que chaque mini-unité centrale suit un pipeline essentiellement en ordre. Ces mini-unités centrales ont plusieurs pipelines superscalaires parallèles plutôt qu'un seul pipeline. "" "
sans travail
4

Que pensez-vous qu'il se soit passé: tous les ingénieurs d'Intel, d'AMD et d'IBM ont lu qu'un pipeline ne peut produire qu'un seul résultat par cycle, et ils ont répondu: "Eh bien, voilà, nous ne pouvons pas rendre ces processeurs plus rapides". Ou ont-ils lu ceci et dit: "Je ne peux pas livrer plus d'un résultat par cycle? Nous verrons à ce sujet!".

Pour une bonne introduction à l'architecture Haswell, par exemple, vous pouvez suivre ce lien http://www.realworldtech.com/haswell-cpu/ ou vous pouvez simplement aller sur le site Web d'Intel et y trouver un peu de documentation.

Chaque cœur du processeur Haswell possède un grand nombre d'unités d'exécution, qui peuvent effectuer des opérations indépendamment les unes des autres, de sorte que plusieurs opérations peuvent être effectuées en parallèle. Ensuite, le processeur Haswell dispose de plusieurs unités d’exécution qui gèrent les opérations vectorielles d’une taille maximale de 256 bits. Une opération vectorielle peut par exemple effectuer quatre opérations à virgule flottante double précision ou huit opérations à virgule flottante simple précision en une opération vectorielle. Et enfin, le processeur Haswell prend en charge "multiplie-addition fusionné", ce qui signifie que calculer un temps b plus c ne représente qu'une seule opération.

Le maximum théorique, étant donné que Haswell dispose de deux unités capables de multiplier-ajouter fondu, est de deux opérations de multiplication-addition fondues par cycle, chaque opération effectuant huit multiplications simple précision plus des ajouts ou 32 opérations en virgule flottante simple précision.

Le processeur 3630 ne figure pas dans la liste de prix la plus récente d’Intel, mais il existe des modèles tels que le 3740QM à quatre cœurs. Ainsi, au lieu de 32, vous pouvez obtenir 128 opérations en virgule flottante. C'est le maximum théorique. Atteindre la moitié de ces objectifs dans la vie réelle est un défi, mais pas impossible pour des tâches appropriées. Il existe d'autres processeurs disponibles avec jusqu'à 15 cœurs (à des prix que même les fanatiques de jeux les plus fanatiques ne paieront pas).

Donc, vous avez une combinaison de plusieurs multiplicateurs:

  1. Plusieurs cœurs par processeur.
  2. (L'hyperthreading, non mentionné auparavant, vous permet de vous rapprocher des limites théoriques)
  3. L'opération de multiplication-addition fusionnée effectue deux opérations arithmétiques ne comptant que pour une seule.
  4. Vecteurs 256 bits effectuant 8 opérations ne comptant que pour un.
  5. Deux unités d’exécution vectorielle capables de gérer l’addition fusionnée-multipliée.

8.6 opérations par cycle n'est pas trop difficile à réaliser. Même 8,6 opérations par cycle et par cœur ne sont pas trop difficiles.

gnasher729
la source
Je me demande s’il serait pratique ou avantageux de concevoir un processeur avec des cœurs sous x86 et d’autres avec un jeu d’instructions optimisé pour un comportement superscalaire. Je sais qu'Intel et AMD font des choses assez étonnantes pour contourner les limites du jeu d'instructions x86, mais dans certains cas, je penserais que connaître certaines choses que le jeu d'instructions actuel ne peut pas exprimer serait utile. Par exemple, des versions distinctes d' ADDinstructions selon que le dépassement de capacité ne doit pas être affecté ou doit être défini lorsque le dépassement se produit (et non définie si ce n'est pas le cas).
Supercat
1
Je suis attristé par le fait qu’aujourd’hui, de nombreuses langues ne vérifient pas le débordement. Je sais que Java est à peu près bloqué par les exigences sémantiques, mais dans des langages tels que C # qui incluent à la fois des opérateurs arithmétiques piégeurs et non intercepteurs, la seule bonne raison que je vois de ne pas piéger les débordements est due à un comportement d'encapsulation. À l'heure actuelle, la vérification des débordements peut imposer une pénalité de vitesse importante, mais si un langage machine a été conçu autour de l'idée que le recouvrement des débordements n'a pas besoin d'être précis tant que le code peut garantir qu'aucun débordement ne s'est produit avant l'exploitation ...
supercat
... atteignant certains points critiques, il devrait être possible de réduire à néant le surcoût lié au trop-plein. Si le code effectue un calcul, puis stocke une valeur dans un emplacement qui sera abandonné si le premier calcul déborde, il ne devrait pas être nécessaire de différer le stockage jusqu'à ce que le processeur sache si le premier calcul aboutit, mais le processeur n'a actuellement aucun moyen de le faire. de savoir que. Si le code pouvait simplement effectuer toutes les opérations pouvant être effectuées en toute sécurité, qu'il y ait ou non débordement, et ensuite vérifier si des débordements incorrects se produisaient sur l'un d'entre eux ...
supercat
... cela semblerait devoir aider à réduire les dépendances d'exécution.
Supercat
2

La référence Drystone date de 1984, et la machine nominale 1 MIPS VAX correspondante n’est pas très efficace au point de vue moderne. Même un Cortex M3 délivre 1,25 DMPIS / MHz.

Les processeurs d'architecture Intel Core peuvent en effet exécuter plusieurs instructions en parallèle dans un même cœur, car plusieurs unités de calcul sont présentes.

Turbo J
la source
1

J'ai beaucoup appris de Jon "Hannibal" Stokes d'Ars Technica, d'excellents articles sur le sujet de l'architecture des microprocesseurs. Les articles sont un peu datés (ils semblent être d’environ 2004), mais restent très pertinents.

Certains liens vers la partie suivante d'un article sont rompus, mais il semble que vous puissiez les réparer vous-même en comparant soigneusement l'URL de la première partie et l'URL rompue de la page suivante (par exemple, en ajoutant m-quelque chose dans l'URL).

(oui, c’est une réponse en lien seulement glorifié, désolé; les articles sont trop bons pour ne pas les mentionner)

marcelm
la source