SSE

**SSE** eli *Streaming SIMD Extensions* (aluksi ISSE,  , myöhemmin  ) on Intelin SIMD-käskykantalaajennus (Single Instruction, Multiple Data; yksi käsky, paljon dataa) IA-32-käskykantaan. SSE tuli käyttöön vuonna 1999 Pentium III -suorittimessa.

SSE lisää suorittimeen kahdeksan 128-bittistä rekisteriä (XMM0–XMM07) ja 70 kpl näitä käyttäviä käskyjä. Käskykannasta löytyy mm. käskyjä joilla rekistereille voidaan laskea rinnakkain neljää 32-bittistä liukulukuoperaatiota.

SSE tehostaa erityisesti 3D-grafiikan geometriamuunnosten laskemista. 
Laajennus tuplasi Pentium III:n liukulukusuorituskyvyn lisäten suorittimen ytimen pinta-alaa vain kymmenyksellä. Käskykannan avulla Pentium III pystyi reaaliaikaiseen MPEG-1 ja MPEG-2-videon purkuun ja soittamaan DVD-levyjä 30 ruutua sekunnissa siten että aikaa jäi vielä muillekin ohjelmille.
Surkuhupaisasti sitä mainostettiin alun perin Internetin käyttöä nopeuttavana laajennuksena, mistä alkuperäinen nimikin tuli.

Koska käskykanta lisäsi suorittimen rekisterien määrää, tulee tämä huomioida tilanteissa, joissa suorittimen tila piti tallettaa, kuten esimerkiksi ohjelmasta toiseen vaihtaessa, joten SSE-käskyjen käyttö vaatii tukea alla olevalta käyttöjärjestelmältä. Jotta ohjelmat eivät voisi yrittää käyttää SSE-käskyjä ilman sitä tukevaa käyttöjärjestelmää, mistä seuraisi ohjelmien virheellistä toimintaa, suorittimeen lisättiin uusi toimintatila. SSE-tietoinen käyttöjärjestelmä asettaa suorittimen tähän toimintatilaan, ja vasta tämän jälkeen SSE-käskyt ovat käytettävissä.

Ensimmäinen SSE-käskykantaa tukenut suoritin oli Intelin Pentium III, joka julkaistiin  alkuvuodesta 1999. AMD oli vajaata vuotta aikaisemmin julkaissut oman 3DNow!-käskykantansa K6-2-suorittimen myötä. 3DNow! puolestaan oli "oikein tehty" korvaaja Intelin alkuperäiselle MMX-käskylaajennukselle, joka ei osannut käsitellä kuin kokonaislukuja, ja sitä käytettäessä esti suorittimen liukulukumatematiikan käytön. SSE ja 3DNow! olivat keskenään kilpailevia käskykantalaajennoksia, ja ajan myötä SSE vei voiton mm. Intelin suuremman markkina-aseman ja paremman kääntäjätuen ansiosta, ja nykyisin ohjelmat optimoidaan tyypillisesti käyttämään SSE-käskyjä mutta ei 3DNow!-käskyjä. AMD otti SSE-käskykannan käyttöön Athlon XP-suorittimessaan vuonna 2001. SSE-käskykantaa on myöhemmin laajennettu SSE2-käskyillä.

## SSE:n kehitysversiot

* SSE2 tuli käyttöön Pentium 4:ssa. Se lisäsi 144 uutta käskyä, tuen kaksoistarkkuuden (64-bitin) liukuluvuille, sekä kokonaislukuoperaatiot, jotka käyttävät SSE-rekistereitä. Näin se korvasi täysin epäonnistuneen MMX:n, sekä koko Intel 8087:n liukukäskykannan.

* SSE3 eli *Prescott New Instructions* on SSE2:n edelleen kehitetty versio, joka lisäsi muutamia signaalinkäsittelyyn (jatkuvaan datavirtaan) suuntautuneita käskyjä ja säikeidenhallintaa.

* SSSE3 on pieni Core Microarchitecturen (2006) laajennus SSE3:een, joka lisäsi 16 käskyä sanan tavujen permutointiin, 16-bittisten kiinteän pilkun lukujen kertomiseen oikein toimivalla pyöristyksellä.

* SSE4 on suuri muutos, joka esiteltiin syyskuussa 2006 ja otettiin käyttöön vuonna 2008 julkaistussa "Nehalem"-suorittimessa.

## SSE-komentojen käyttö

SSE-komentoja voidaan käyttää erikseen assembly-ohjelmilla tai *inline* komennoilla ylemmän tason kielestä kuten C- tai C++-kielestä.

Triviaali esimerkki kahden *vektorin* yhteenlaskemisesta SSE-komentoja käyttäen C++-kielisestä ohjelmasta (*inline*-assembly):

```cpp
struct vec_t { float v[4]; };
vec_t v1 = {1.1, 1.2, 1.3, 1.4};
vec_t v2 = {1.2, 2.2, 3.2, 4.2};
vec_t vec_res = {0.0, 0.0, 0.0, 0.0};
__asm 
{
    movaps xmm0, [v1] ; v1 arvot lähteestä rekisteriin
    addps xmm0, [v2]  ; v1+v2 (alkioiden summat)
    movaps [vec_res], xmm0 ; kopio rekisteristä kohdemuuttujaan
}
```


Kääntäjien mukana on tyypillisesti *intrinsics* standardifunktiot suoritinkohtaisten alemman tason operaatioiden käyttämiseen ilman inline-assemblya. Esimerkiksi Microsoftin kääntäjä toteuttaa standardifunktiot, jotka vastaavat suoraan x86-käskykannan laajennuksia. Samoin tekevät myös mm. Intelin C/C++ kääntäjä ja GCC.

Suoritin odottaa, että muuttujat *tasataan* () tiettyyn kokoon, joka SSE-komennoilla tarkoittaa 16-tavuista (128-bittistä) tasausta. Koska `float` on tyypillisesti neljä tavua tämä tapahtuu automaattisesti neljän muuttujan *taulukolla* (). Muuttujatyypille tasaus asetetaan `__declspec` määrittelyllä seuraavasti:

```cpp
__declspec(align(16)) struct vec_t { float v[4]; };
```


Koska kyseessä on käskylaajennus tavalliseen käskykantaan normaalisti tarkistettava että suoritin tukee laajennusta.

## Lähteet

## Aiheesta muualla
* AMD:n käskykantamanuaalit 
* Intelin käskykantamanuaalit