, généralement abrégé SSE, est un jeu d'instructions pour microprocesseurs x86 implémenté pour la première fois par Intel en 1999, sur le Pentium , en réponse au 3DNow! d'AMD apparu un an plus tôt. Le fonctionnement est de type SIMD et ajoute 70 instructions-machine supplémentaires.
Il a été d'abord dévoilé sous le nom KNI signifiant « » (Nouvelles instructions Katmai en anglais, Katmai étant le nom de code pour la première version du cœur du Pentium ). Pendant le projet Katmai, Intel désirait le distinguer de ses précédentes lignes de produit et particulièrement de son produit phare, le Pentium . AMD ajouta le support d'instructions SSE avec ses processeurs Athlon XP. Il fut ultérieurement renommé ISSE, ce qui signifie « » (Extensions pour flux SIMD d'Intel en anglais), puis SSE.
Les SIMD et MMX IA-32 se sont globalement révélés décevants. Le MMX avait deux problèmes principaux : il réutilisait des registres à virgule flottante x87 existants, rendant le processeur incapable de fonctionner simultanément en virgule flottante et en donnée SIMD et ne fonctionnait que sur les entiers.
Registres
Le SSE a originellement ajouté huit nouveaux registres nommés XMM0 à XMM7. Les extensions x64 d'Intel et AMD ajoutent huit nouveaux registres de XMM8 à XMM15. Il y a également un nouveau registre de contrôle/statut nommé MXCSR.
Chaque registre compacte ensemble quatre nombres flottants simple précision . Les opérations SIMD entières peuvent toujours être effectuées par les huit registres MMX.
Instructions SSE Le SSE a à la fois introduit des instructions scalaires et de virgule flottante compactée.
Instructions à virgule flottante
Déplacement de donnée de mémoire à registre / Registre à mémoire / Registre à registre. Scalaire - MOVSS Compacté - MOVAPS, MOVUPS, MOVLPS, MOVHPS, MOVLHPS, MOVHLPS Arithmétique Scalaire - ADDSS, SUBSS, MULSS, DIVSS, RCPSS, SQRTSS, MAXSS, MINSS, RSQRTSS Compacté - ADDPS, SUBPS, MULPS, DIVPS, RCPPS, SQRTPS, MAXPS, MINPS, RSQRTPS Comparaison Scalaire - CMPSS, COMISS, UCOMISS Compacté - CMPPS Mélange de données et dépaquetage. Compacté - SHUFPS, UNPCKHPS, UNPCKLPS Conversion de type de donnée Scalaire - CVTSI2SS, CVTSS2SI, CVTTSS2SI Compacté - CVTPI2PS, CVTPS2PI, CVTTPS2PI Opération logiques bit à bit Compacté - ANDPS, ORPS, XORPS, ANDNPS
Instructions entières
Arithmétiques PMULHUW, PSADBW, PAVGB, PAVGW, PMAXUB, PMINUB, PMAXSW, PMINSW Mouvement de données PEXTRW, PINSRW Autres PMOVMSKB, PSHUFW
Autres instructions Gestion du registre MXCSR LDMXCSR, STMXCSR Gestion de la mémoire et du cache MOVNTQ, MOVNTPS, MASKMOVQ, PREFETCH0, PREFETCH1, PREFETCH2, PREFETCHNTA, SFENCE
Exemple Le simple exemple suivant montre les avantages de l'utilisation du SSE.
Les instructions SSE1 fonctionnent avec des nombres flottants simple précision, c'est-à-dire stockés sur 4 octets. Une variable de vecteur 4 dimensions adaptée aux registres est donc constituée de 16 octets. Si les données sont alignées sur 128 bits, on peut les lire avec l'instruction movaps, sinon si on ne peut pas le garantir, on doit utiliser movups. Sinon, on obtient une erreur à l'exécution.
Pour l'opération d'addition vectorielle le x87 requiert quatre instructions d'addition flottantes pour additionner entre eux deux vecteurs de dimension 4 à simple précision.
vec_res.x = v1.x + v2.x; vec_res.y = v1.y + v2.y; vec_res.z = v1.z + v2.z; vec_res.w = v1.w + v2.w;
Cela correspond à quatre instructions FADD du x87 en code objet. Alors que le pseudo-code suivant montre qu'une seule instruction (addition compacte) peut remplacer les quatre instructions d'addition scalaire. On suppose ici que les données sont alignées en mémoire sur 128 bits.
movaps xmm0,adresse-de-v1 ;xmm0 = v1.w | v1.z | v1.y | v1.x addps xmm0,adresse-de-v2 ;xmm0 = v1.w+v2.w | v1.z+v2.z | v1.y+v2.y | v1.x+v2.x movaps adresse-du-vec_res,xmm0
C'est néanmoins en utilisant au maximum les registres pour stocker les valeurs lors d'opération complexes que l'on obtient vraiment un gain en vitesse.
Normaliser un vecteur
Supposons que le registre xmm0 contienne un vecteur à trois dimensions à normaliser (la étant à zéro). En utilisant temporairement les registres xmm6 et xmm7, on peut normaliser le vecteur ainsi : //Entrée: xmm0 contient un vecteur à normaliser movaps xmm6, xmm0 //effectue une copie du vecteur dans xmm6 mulps xmm0, xmm0 //carré de chaque composante //mix1 movaps xmm7, xmm0 shufps xmm7, xmm7, $4e addps xmm0, xmm7 //additionne les composantes mélangées //mix2 movaps xmm7, xmm0 shufps xmm7, xmm7, $11 addps xmm0, xmm7 //additionne les composantes mélangées //1/sqrt rsqrtps xmm0, xmm0 //inverse de la racine carrée (= longueur) mulps xmm0, xmm6 //que multiplie le vecteur initial //Sortie: xmm0 contient le vecteur normalisé
Produit vectoriel
Supposons que les variables vS1 et vS2 contiennent deux vecteurs définissant un plan, ayant 3 composantes et 1 composante non utilisée. Le produit vectoriel permet d'obtenir un vecteur normal, c'est-à-dire perpendiculaire à ce plan. En utilisant temporairement les registres xmm6 et xmm7, on peut calculer le produit vectoriel et le stocker dans xmm0 comme cela :
movups xmm6, vS1 //le U signifie qu'on ne suppose pas que les données sont alignées à 128 bits shufps xmm6, xmm6, 9 //= 1 + 8, c'est-à-dire une rotation des 3 composantes movups xmm7, vS2 shufps xmm7, xmm7, 18 //= 2 + 16, c'est-à-dire une rotation dans l'autre sens movaps xmm0,xmm6 //premier produit pour chaque composante mulps xmm0,xmm7 movups xmm6, vS1 shufps xmm6, xmm6, 18 movups xmm7, vS2 shufps xmm7, xmm7, 9 mulps xmm7,xmm6 //deuxième produit retranché pour chaque composante subps xmm0,xmm7 //Sortie: xmm0 contient le produit vectoriel de vS1 et vS2
Évolutions Le SSE2 créé pour le Pentium 4 ajoute des instructions flottantes double précision () et étend les instructions MMX avec des opérations sur les registres XMM . Le SSE3 sur le Pentium Prescott, ajoute des instructions mathématiques orientées DSP et quelques instructions de gestion de processus. Le SSSE3 ajoute 16 nouveaux qui incluent la permutation des octets dans un mot, la multiplication des nombres à virgule fixe avec un arrondissement correct et des instructions d'accumulation dans un mot. SSSE3 est souvent confondu avec SSE4 car ce terme a été utilisé pendant la phase de développement de la microarchitecture. Le SSE4 est une autre avancée majeure, ajoutant une instruction de produit scalaire, de nombreuses instructions d'additions entières, une instruction popcnt et d'autres instructions. SSE4 arrête le support des registres MMX. Le SSE4 est supporté par la version 'Penryn' de la microarchitecture Core 2 . Le SSE5 prévu initialement pour mi- par AMD et implémenté dans la microarchitecture Bulldozer en , permet, comme dans les processeurs RISC, de préciser dans l'instruction un troisième registre destination, ce qui permet d'économiser un bon nombre d'instructions et devrait intrinsèquement accélérer les calculs. Auparavant, il fallait d'abord copier le contenu du registre destination dans un nouveau registre afin de ne pas détruire les informations précédentes sur theregister.co.uk sur developer.AMD.com.
Notes et références
Voir aussi Articles connexes Jeu d'instructions x86 MMX 3DNow! SSE2, SSE3, SSSE3, SSE4, SSE5
SSE Catégorie:Jeu d'instruction x86