Je lisais cette question très intéressante sur Stack Overflow:
Un des commentaires dit:
"Cela ne sert à rien que sur Haswell, le débit multiplié par FP soit le double de celui de l'addition FP. C'est parce que les ports 0 et 1 peuvent être utilisés pour multiplier, mais seul le port 1 peut être utilisé pour l'ajout. Cela dit, vous pouvez tricher avec -multiply ajoute puisque les deux ports peuvent les faire. "
Pourquoi permettent-ils deux fois plus de multiplications simultanées que l’addition?
cpu
computer-architecture
alu
floating-point
intel
utilisateur1271772
la source
la source
Réponses:
Cela répond éventuellement au titre de la question, sinon au corps:
L'ajout de virgule flottante nécessite l'alignement des deux mantisses avant de les ajouter (en fonction de la différence entre les deux exposants), nécessitant potentiellement une grande quantité variable de décalage avant l'additionneur. Ensuite, il peut être nécessaire de renormaliser le résultat de l'ajout de mantisse, nécessitant éventuellement une autre grande quantité de décalage variable afin de formater correctement le résultat en virgule flottante. Les deux manettes de changement de barillet de mantisse nécessitent donc potentiellement plus de retards de porte, de retards de fil ou de cycles supplémentaires qui dépassent le retard d’un multiplicateur de portage-sauvegarde-sauvegarde-arborescence bien compacté.
Ajouté pour l'OP: Notez que l'addition des longueurs de 2 millimètres et 2 kilomètres ne correspond à 4 pas de l'une ou l'autre unité. Cela est dû à la nécessité de convertir l'une ou l'autre mesure à la même échelle ou à la même représentation unitaire avant l'addition. Cette conversion nécessite essentiellement une multiplication par une puissance de 10. La même chose doit normalement se produire lors de l’addition à virgule flottante, car les nombres à virgule flottante sont une forme d’entiers à l’échelle variable (par exemple, il existe une unité ou un facteur d’échelle, un exposant, associé à chaque numéro). Vous devrez donc peut-être redimensionner l’un des nombres avec une puissance de 2 avant d’ajouter des bits de mantisse bruts afin que les deux représentent les mêmes unités ou la même échelle. Cette mise à l'échelle est essentiellement une forme simple de multiplication par une puissance de 2. Ainsi, l'addition en virgule flottante nécessite une multiplication.(qui, étant une puissance de 2, peut être fait avec un décalage de bit variable ou un décaleur à barillet, ce qui peut nécessiter des fils relativement longs par rapport à la taille des transistors, ce qui peut être relativement lent dans les circuits profonds de lithographie submicronique). Si les deux nombres annulent généralement (parce que l'un est presque négatif de l'autre), il peut être nécessaire de redimensionner le résultat de l'addition afin de formater le résultat de manière appropriée. Ainsi, l’addition peut être lente si elle nécessite en outre 2 étapes de multiplication (pré et post) entourant l’addition binaire d’un nombre brut fixe (fini) de bits de mantisse représentant des unités équivalentes ou une échelle, en raison de la nature du format numérique (virgule flottante IEEE). ).
Ajout n ° 2: En outre, de nombreux points de repère pèsent davantage les FMACS que les additions nues. Dans un MAC fusionné, l'alignement (décalage) de l'addend peut souvent être généralement effectué en parallèle avec le multiply, et la mantisse add peut souvent être incluse dans l'arborescence CSA avant la propagation finale du report.
la source
Dans la multiplication FP, le traitement des exposants s'avère être une simple addition (pour exactement la même raison, la multiplication dans le domaine de journalisation est simplement une addition). Vous avez rencontré des logarithmes, j'espère.
Voyons maintenant combien il est difficile d’ ajouter deux nombres sous forme logarithmique ...
La virgule flottante habite une zone grise entre les domaines linéaire et log, avec des aspects des deux. Chaque nombre FP comprend une mantisse (qui est linéaire) et un exposant (logarithmique). Pour déterminer la signification de chaque bit de la mantisse, vous devez d'abord examiner l'exposant (qui n'est qu'un facteur d'échelle).
En outre, le traitement des exposants dans le cas général nécessite le déplacement de la mantisse en baril deux fois, chaque changement de baril étant en réalité un cas particulier d’une multiplication légèrement simplifiée.
(Le premier décalage aligne les deux entrées sur la même puissance de 2, de sorte qu'un bit de mantisse ait le même poids binaire dans chaque opérande.
Un exemple décimal suffira (bien que binaire soit évidemment utilisé) ...
La seconde redimensionne la sortie ...
Donc, paradoxalement, un ajout de PF implique quelque chose qui ressemble beaucoup à deux multiplications qui doivent être effectuées séquentiellement, avec l'addition de mantisse entre elles. Dans cette optique, la performance rapportée n’est pas si surprenante.
la source
TL: DR : Intel pensant que la latence SSE / AVX FP était plus importante que le débit, ils ont choisi de ne pas l’utiliser sur les unités FMA de Haswell / Broadwell.
Haswell exécute (SIMD) multiplie par FP sur les mêmes unités d'exécution que FMA ( Fused Multiply-Add ), dont il a deux parce que certains codes intensifs en FP peuvent utiliser principalement des FMA pour faire 2 FLOP par instruction. Même latence de 5 cycles que FMA, et que
mulps
sur les processeurs précédents (Sandybridge / IvyBridge). Haswell souhaitait 2 unités FMA, et il n’ya aucun inconvénient à laisser multiplier s’exécuter, car elles ont la même latence que l’unité dédiée à multiplier des processeurs antérieurs.Toutefois, il conserve l’unité d’ajout SIMD FP dédiée à partir de processeurs antérieurs à fonctionner
addps
/addpd
avec une latence de 3 cycles. J'ai lu que le raisonnement possible pourrait être que le code qui ajoute beaucoup de FP ajoute un goulot d'étranglement sur le temps de latence et non sur le débit. Cela est certainement vrai pour une somme naïve d'un tableau avec un seul accumulateur (vectoriel), comme c'est souvent le cas avec la vectorisation automatique de GCC. Mais je ne sais pas si Intel a publiquement confirmé que c’était leur raisonnement.Broadwell est le même ( mais accéléré
mulps
/mulpd
latence 3c tandis que FMA est resté à 5c). Ils ont peut-être pu raccourcir l'unité FMA et obtenir le résultat multiplié avant de faire une addition factice0.0
, ou peut-être quelque chose de complètement différent et beaucoup trop simpliste. BDW est principalement une réduction de HSW avec la plupart des changements mineurs.Dans Skylake, tout FP (y compris l'addition) s'exécute sur l'unité FMA avec une latence de 4 cycles et un débit de 0,5 c, sauf bien sûr div / sqrt et les valeurs booléennes binaires (par exemple, pour la valeur absolue ou la négation). Intel a apparemment décidé que cela ne valait pas plus de silicium pour les ajouts de FP à temps de latence inférieur, ou que le
addps
débit déséquilibré posait problème. De plus, la normalisation des latences permet d'éviter les conflits d'écriture (lorsque 2 résultats sont prêts dans le même cycle), ce qui est plus facile à éviter dans la planification uop. c'est-à-dire simplifie les ports de planification et / ou d'achèvement.Alors oui, Intel a changé cela lors de sa prochaine révision majeure de la microarchitecture (Skylake). La réduction de la latence FMA d'un cycle a permis de réduire considérablement l'avantage d'une unité d'ajout de ressources SIMD dédiée, dans les cas où la latence était liée.
Skylake montre également des signes de préparation d'Intel pour l'AVX512, où l'extension d'un additionneur SIMD-FP séparé à une largeur de 512 bits aurait pris encore plus de place. Skylake-X (avec AVX512) aurait un noyau presque identique à celui de Skylake-client normal, à l'exception d'un cache L2 plus important et (sur certains modèles) d'une unité FMA supplémentaire de 512 bits "boulonnée" sur le port 5.
SKX ferme les SIMU ALU du port 1 lorsque des Uops 512 bits sont en vol, mais il doit être exécuté
vaddps xmm/ymm/zmm
à tout moment. Cela posait le problème d'avoir une unité dédiée FP ADD sur le port 1 et constituait une motivation distincte pour modifier le comportement du code existant.Anecdote: Skylake, KabyLake, Coffee Lake et même Cascade Lake ont été identiques sur le plan microarchitectural à Skylake, à l'exception de Cascade Lake qui a ajouté de nouvelles instructions AVX512. IPC n'a pas changé autrement. Les nouveaux processeurs ont cependant de meilleurs iGPU. Ice Lake (microarchitecture de Sunny Cove) est la première fois depuis plusieurs années que nous voyons une nouvelle microarchitecture (à l'exception du lac Cannon, qui n'a jamais été diffusé à grande échelle).
Les arguments fondés sur la complexité d'une unité FMUL par rapport à une unité FADD sont intéressants mais non pertinents dans ce cas . Une unité FMA comprend tout le matériel de décalage nécessaire pour l’ajout de PF dans le cadre d’une FMA 1 .
Note: Je ne parle pas du x87
fmul
instruction, je veux dire un SSE / AVX SIMD / FP scalaire multiplication ALU supports 32 bits simple précision /float
et 64 bits dedouble
précision (53 bits mantisse mantisse aka). par exemple des instructions commemulps
oumulsd
. La valeur x87 réelle sur 80 bitsfmul
n’est encore que de 1 / débit d’horloge sur Haswell, sur le port 0.Les processeurs modernes disposent de suffisamment de transistors pour résoudre les problèmes lorsque cela en vaut la peine et quand ils ne causent pas de problèmes de retard de propagation à une distance physique. Surtout pour les unités d'exécution qui ne sont actives que de temps en temps. Voir https://en.wikipedia.org/wiki/Dark_silicon et ce document de conférence de 2011: Dark Silicon et la fin de la mise à l'échelle multicœur. C’est ce qui permet aux processeurs d’obtenir des débits massifs FPU et entiers énormes, mais pas les deux en même temps (car ces différentes unités d’exécution se trouvent sur le même port de dispatch et se font concurrence). Dans un grand nombre de codes soigneusement réglés qui ne gênent pas la bande passante mem, ce ne sont pas les unités d'exécution principales qui constituent le facteur limitant, mais le débit des instructions frontales. ( les noyaux larges sont très chers ). Voir aussi http://www.lighterra.com/papers/modernmicroprocessors/ .
Avant Haswell
Avant HSW , les processeurs Intel tels que Nehalem et Sandybridge avaient multiplié SIMD FP sur le port 0 et SIMD FP ajouté le port 1. Il existait donc des unités d'exécution distinctes et le débit était équilibré. ( https://stackoverflow.com/questions/8389648/how-do-i-achieve-the-theoretical-maximum-of-4-flops-per-cycle
Haswell a introduit le support FMA dans les processeurs Intel (quelques années après qu'AMD ait introduit FMA4 dans Bulldozer, après qu'Intel les ait simulés en attendant le plus tard possible pour annoncer publiquement qu'ils allaient implémenter FMA à 3 opérandes, et non à 4 opérandes non. -destructive-destination FMA4). Anecdote: AMD Piledriver était toujours le premier processeur x86 avec FMA3, environ un an avant Haswell en juin 2013.
Cela nécessitait un piratage important des internes pour même supporter un seul uop avec 3 entrées. Quoi qu'il en soit, Intel a tout compris et a profité des transistors de plus en plus réduits pour équiper deux unités FMA SIMD 256 bits, faisant ainsi de Haswell (et de ses successeurs) un faste pour la mathématique en PF.
Une cible de performance qu'Intel aurait pu imaginer était le produit matriciel et vecteur à points denses BLAS. Ces deux peuvent utiliser la plupart FMA et ne nécessitent pas simplement ajouter.
Comme je l’ai mentionné plus tôt, certaines charges de travail qui ajoutent principalement ou simplement des FP sont goulot d’étranglement sur la latence de l’ajout, (surtout) pas du débit.
Note de bas de page 1 : Et avec un multiplicateur de
1.0
, FMA peut littéralement être utilisé pour l'addition, mais avec une latence inférieure à celle d'uneaddps
instruction. Cela est potentiellement utile pour des charges de travail telles que la somme d'un tableau actif dans le cache L1d, où la capacité de débit supplémentaire ajoutée compte plus que la latence. Cela n’est utile que si vous utilisez plusieurs accumulateurs vectoriels pour masquer la latence, bien sûr, et pour laisser 10 opérations FMA en vol dans les unités d’exécution FP (latence 5c / débit 0,5c = produit de latence * bande passante 10). Vous devez également procéder de la sorte lorsque vous utilisez FMA pour un produit vectoriel à points .Voir l'écriture de David Kanter sur la microarchitecture de Sandybridge, qui présente un schéma de principe indiquant les EU sur le port correspondant à NHM, SnB et la famille de bulldozers AMD. (Voir également les tableaux d'instructions d' Agner Fog et le guide de microarch d'optimisation asm, ainsi que https://uops.info/ qui propose également des tests expérimentaux sur les uops, les ports et le temps de latence / débit de presque chaque instruction sur de nombreuses générations de microarchitectures Intel.)
Également associé: https://stackoverflow.com/questions/8389648/how-do-i-achieve-the-theoretical-maximum-of-4-flops-per-cycle
la source
[cpu-architecture]
,[performance]
,[x86-64]
,[assembly]
et[sse]
. J'ai écrit une réponse sur du code C ++ pour tester la conjecture de Collatz plus rapidement qu'un assemblage écrit à la main - pourquoi? que beaucoup de gens pensent est bon. Aussi ce à propos de OoO exécution en pipeline.Je vais regarder cette partie:
"Pourquoi est-ce qu'ils autoriseraient " ...
TL; DR - parce qu'ils l'ont conçu de cette façon. C'est une décision de gestion. Bien sûr, il existe des réponses de la mantisse et des décaleurs de bits, mais ce sont des éléments qui entrent dans la décision de gestion.
Pourquoi l'ont-ils conçu de cette façon? La réponse est que les spécifications sont faites pour atteindre certains objectifs. Ces objectifs incluent la performance et le coût. Les performances ne sont pas axées sur les opérations, mais plutôt sur une référence comme FLOPS ou FPS dans Crysis.
Ces tests auront une combinaison de fonctions, certaines pouvant être traitées en même temps.
Si les concepteurs pensent qu'avoir deux fonctions du widget A le rend beaucoup plus rapide, plutôt que deux fonctions du widget B, ils choisiront le widget A. L'implémentation de deux de A et deux de B coûtera plus cher.
En regardant en arrière lorsque les pipelines superscalaires et super (avant les multicœurs) sont devenus courants sur les puces commerciales, ils étaient là pour améliorer les performances. Le Pentium a deux tuyaux et aucun vecteur ne s'unit. Haswell dispose de davantage de tuyaux, d'unités vectorielles, d'un tuyau plus profond, de fonctions dédiées, etc. Pourquoi n'y en a-t-il pas deux? Parce qu'ils l'ont conçu de cette façon.
la source
Ce diagramme d'Intel peut aider:
Il semble qu'ils aient donné à chaque unité un FMA (multiplié-addition fusionné) ainsi qu'un multiplicateur et un simple additionneur. Ils peuvent ou ne peuvent pas partager le matériel en dessous.
La question de savoir pourquoi est beaucoup plus difficile de répondre sans justifications de conception interne, mais le texte dans la boîte violette nous donne un soupçon de « doubles pointe FLOP »: le processeur ciblera un ensemble de repères, provenant de cas d'utilisation réels. Le FMA est très populaire dans ces pays car c’est l’unité de base de la multiplication matricielle. L'addition nue est moins populaire.
Comme il a été souligné, vous pouvez utiliser les deux ports pour effectuer une addition avec une instruction FMA où le paramètre de multiplication est 1, calculant (A x 1) + B. Cela sera légèrement plus lent qu'une addition nue.
la source
Jetons un coup d'oeil aux étapes fastidieuses:
Addition: Alignez les exposants (peut être une opération de décalage massive). Un additionneur 53 bits. Normalisation (jusqu'à 53 bits).
Multiplication: Un réseau additionneur massif permettant de réduire de 53 x 53 produits un bit à la somme de deux nombres de 106 bits. Un additionneur de 106 bits. Normalisation. Je dirais que réduire le nombre de bits à deux chiffres peut être fait aussi rapidement que l’additionneur final.
Si vous pouvez définir un temps de multiplication variable, vous avez l’avantage que la normalisation ne changera que d’un bit la plupart du temps et que vous pourrez détecter les autres cas très rapidement (entrées dénormalisées, ou le nombre d’exposants est trop petit).
De plus, le recours à des étapes de normalisation est très courant (ajout de nombres de taille différente, soustraction de nombres proches). Donc, pour la multiplication, vous pouvez vous permettre d’avoir une voie rapide et de prendre un coup énorme pour la voie lente; pour plus vous ne pouvez pas.
PS Lecture des commentaires: Il est logique que l’ajout de nombres dénormalisés n’entraîne aucune pénalité: cela signifie simplement que parmi les bits décalés pour aligner les exposants, beaucoup sont des zéros. Et le résultat dénormalisé signifie que vous arrêtez de décaler pour supprimer les zéros non significatifs si cela rend l’exposant trop petit.
la source
-ffast-math
ensembles FTZ / DAZ (réinitialiser les dénormaux à zéro) permet de le faire au lieu de prendre une assistance de PF.