Estensioni SIMD in streaming

Questo articolo è una bozza sui computer .

Puoi condividere la tua conoscenza migliorandola ( come? ) secondo le raccomandazioni dei progetti corrispondenti .

Streaming SIMD Extensions , comunementeabbreviato SSE, è un insieme di 70 istruzioni aggiuntive permicroprocessori x86, rilasciato nel1999sulPentium III in risposta a3DNow! diAMD èapparso 1 anno prima. L'operazione è di tipoSIMD.

È stato svelato per la prima volta con il nome KNI che significa "  Katmai New Instructions  " ( Katmai New Instructions in inglese , Katmai è il nome in codice per la prima versione del core Pentium III ). Durante il progetto Katmai, Intel ha voluto distinguerlo dalle sue precedenti linee di prodotti e in particolare dal suo prodotto di punta, il Pentium II . AMD ha aggiunto il supporto per le istruzioni SSE con i suoi processori Athlon XP . Successivamente è stato ribattezzato ISSE, che sta per "  Intel Streaming SIMD Extensions  ", quindi SSE.

Nel complesso, i SIMD e gli MMX IA-32 si sono rivelati deludenti. L'MMX aveva due problemi principali: riutilizzava i registri in virgola mobile esistenti, rendendo il processore incapace di funzionare contemporaneamente in virgola mobile e dati SIMD e funzionava solo su numeri interi.

Registri

L'SSE ha originariamente aggiunto otto nuovi registri a 128 bit denominati da XMM0 a XMM7. Le estensioni Intel e AMD x64 aggiungono otto nuovi registri da XMM8 a XMM15. C'è anche un nuovo registro di controllo/stato a 32 bit chiamato MXCSR.

Ciascun registro compatta insieme quattro numeri a virgola mobile a precisione singola a 32 bit. Le operazioni SIMD complete possono ancora essere eseguite dagli otto registri MMX a 64 bit.

Istruzioni SSE

L'SSE ha introdotto istruzioni in virgola mobile sia scalari che compresse.

Istruzioni in virgola mobile

Istruzioni complete

Ulteriori istruzioni

Esempio

Il seguente semplice esempio mostra i vantaggi dell'utilizzo di ESS.

Le istruzioni SSE1 funzionano con numeri in virgola mobile a precisione singola, ovvero numeri memorizzati in 4 byte. Una variabile vettoriale quadridimensionale adatta ai registri è quindi composta da 16 byte. Se i dati sono allineati a 128 bit, possono essere letti con l'istruzione movaps , altrimenti se non possono essere garantiti, devono essere utilizzati i movup . Altrimenti, riceviamo un errore in fase di esecuzione.

Per l'operazione di addizione vettoriale, x87 richiede quattro istruzioni di addizione in virgola mobile per aggiungere due vettori quadridimensionali a precisione singola tra loro.

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;

Ciò corrisponde a quattro istruzioni FADDx87 nel codice oggetto. Considerando che il seguente pseudo-codice mostra che una singola istruzione "packed-add" a 128 bit può sostituire tutte e quattro le istruzioni di addizione scalare. Si presume qui che i dati siano allineati in memoria su 128 bit.

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

È tuttavia utilizzando al massimo i registri per memorizzare i valori durante operazioni complesse che si ottiene realmente un guadagno di velocità.

Normalizza un vettore

Supponiamo che il registro xmm0 includa un vettore tridimensionale da normalizzare (il 4 °  componente è zero). Utilizzando temporaneamente i registri xmm6 e xmm7, possiamo normalizzare il vettore come segue:

//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é

Prodotto vettoriale

Supponiamo che le variabili vS1 e vS2 contengano due vettori che definiscono un piano, avente 3 componenti e 1 componente inutilizzata. Il prodotto vettoriale permette di ottenere un vettore normale, cioè perpendicolare a questo piano. Utilizzando temporaneamente i registri xmm6 e xmm7, possiamo calcolare il prodotto incrociato e memorizzarlo in xmm0 in questo modo:

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

evoluzioni

Note e riferimenti

  1. (it) [1]
  2. (it) [2]
  3. (it) boost pad AMD single thread con estensioni x86 su theregister.co.uk
  4. (in) Set di istruzioni a 128 bit SSE5 su developer.AMD.com

Articoli Correlati