Moderneissa grafiikkakorteissa hyödynnetään myös samanlaista toimintamallia



Samankaltaiset tiedostot
Ongelma(t): Miten mikro-ohjelmoitavaa tietokonetta voisi ohjelmoida kirjoittamatta binääristä (mikro)koodia? Voisiko samalla algoritmin esitystavalla

TIEP114 Tietokoneen rakenne ja arkkitehtuuri, 3 op. Assembly ja konekieli

TIEP114 Tietokoneen rakenne ja arkkitehtuuri, 3 op. Assembly ja konekieli

Sulautettujen järjestelmien skaala on niin laaja, että on erittäin vaikea antaa yleispätevää kuvausta siitä millainen on sulautettu järjestelmä.

Ongelma(t): Miten tietokoneen komponentteja voi ohjata siten, että ne tekevät yhdessä jotakin järkevää? Voiko tietokonetta ohjata (ohjelmoida) siten,

Intel Pentium Pro -prosessori. tietokonearkkitehtuurit, syksy -96 Ari Rantanen

Rinnakkaistietokoneet luento S

Yhtälöryhmät 1/6 Sisältö ESITIEDOT: yhtälöt

Concurrency - Rinnakkaisuus. Group: 9 Joni Laine Juho Vähätalo

CUDA. Moniydinohjelmointi Mikko Honkonen

Matriisit ovat matlabin perustietotyyppejä. Yksinkertaisimmillaan voimme esitellä ja tallentaa 1x1 vektorin seuraavasti: >> a = 9.81 a = 9.

Ohjelmointiharjoituksia Arduino-ympäristössä

Tiedon esitysmuodot. Luento 6 (verkkoluento 6) Lukujärjestelmät Kokonaisluvut, liukuluvut Merkit, merkkijonot Äänet, kuvat, muu tieto

LOAD R1, =2 Sijoitetaan rekisteriin R1 arvo 2. LOAD R1, 100

Rinnakkaisuuden hyväksikäyttö peleissä. Paula Kemppi

tään painetussa ja käsin kirjoitetussa materiaalissa usein pienillä kreikkalaisilla

Sisällys. 16. Ohjelmoinnin tekniikkaa. Aritmetiikkaa toisin merkiten. Aritmetiikkaa toisin merkiten

Ohjelmointitaito (ict1td002, 12 op) Kevät Java-ohjelmoinnin alkeita. Tietokoneohjelma. Raine Kauppinen

16. Ohjelmoinnin tekniikkaa 16.1

Osoitin ja viittaus C++:ssa

Algoritmit 1. Luento 3 Ti Timo Männikkö

ELM GROUP 04. Teemu Laakso Henrik Talarmo

TIES325 Tietokonejärjestelmä. Jani Kurhinen Jyväskylän yliopisto Tietotekniikan laitos

Liukulukulaskenta. Pekka Hotokka

16. Ohjelmoinnin tekniikkaa 16.1

Sisällys. 17. Ohjelmoinnin tekniikkaa. Aritmetiikkaa toisin merkiten. for-lause lyhemmin

Ongelma(t): Miten tietokoneen käyttöjärjestelmä toimii sisäisesti, jotta resurssit saadaan tehokkaaseen käyttöön?

Luento 3 (verkkoluento 3) Ttk-91 konekielinen ohjelmointi. Ohjelman esitysmuoto Konekielinen ohjelmointi ttk-91:llä (Titokone, TitoTrainer)

Java-kielen perusteet

Javan perusteet. Ohjelman tehtävät: tietojen syöttö, lukeminen prosessointi, halutun informaation tulostaminen tulostus tiedon varastointi

AS C-ohjelmoinnin peruskurssi 2013: C-kieli käytännössä ja erot Pythoniin

Chapel. TIE Ryhmä 91. Joonas Eloranta Lari Valtonen

Teemun juustokakku Rekisterien, välimuistin, muistin, levymuistin ja magneettinauhan nopeudet suhteutettuna juuston hakuaikaan juustokakkua tehdessä?

Pythonin alkeet Syksy 2010 Pythonin perusteet: Ohjelmointi, skriptaus ja Python

ImageRecognition toteutus

815338A Ohjelmointikielten periaatteet Harjoitus 4 vastaukset

4. Lausekielinen ohjelmointi 4.1

Algoritmit 2. Luento 10 To Timo Männikkö

Tähtitieteen käytännön menetelmiä Kevät 2009 Luento 4: Ohjelmointi, skriptaus ja Python

PRINCIPLES OF PROGRAMMING LANGUAGES - DEBUGGER

Kombinatorisen logiikan laitteet

TAMPEREEN TEKNILLINEN YLIOPISTO Digitaali- ja tietokonetekniikan laitos. Harjoitustyö 4: Cache, osa 2

Java-kielen perusteet

Kertausluento luennoista 1-3 1

Jouni Huotari OLAP-ohjetekstit kopioitu Microsoftin ohjatun OLAP-kuution teko-ohjeesta. Esimerkin kuvaus ja OLAP-määritelmä

TIETOJEN TUONTI TIETOKANNASTA + PIVOT-TAULUKON JA OLAP-KUUTION TEKO

Matematiikan tukikurssi, kurssikerta 3

Algebra I, harjoitus 5,

811120P Diskreetit rakenteet

58131 Tietorakenteet ja algoritmit (syksy 2015)


Harjoitus 3 ( )

815338A Ohjelmointikielten periaatteet Harjoitus 3 vastaukset

Tyyppejä ja vähän muutakin. TIEA341 Funktio ohjelmointi 1 Syksy 2005

Monipuolinen esimerkki

Harjoitus 3 (viikko 39)

Ohjelmointitaito (ict1td002, 12 op) Kevät Java-ohjelmoinnin alkeita. Tietokoneohjelma. Raine Kauppinen

Luku 6. Dynaaminen ohjelmointi. 6.1 Funktion muisti

Lumejärjestelmä Xen. Reino Miettinen

etunimi, sukunimi ja opiskelijanumero ja näillä

ITKP102 Ohjelmointi 1 (6 op)

7. Näytölle tulostaminen 7.1

Perusteet. Pasi Sarolahti Aalto University School of Electrical Engineering. C-ohjelmointi Kevät Pasi Sarolahti

7.4 Sormenjälkitekniikka

15. Ohjelmoinnin tekniikkaa 15.1

Taitaja semifinaali 2010, Iisalmi Jääkaapin ovihälytin

Luku 8. Aluekyselyt. 8.1 Summataulukko

Luento 1 Tietokonejärjestelmän rakenne

Luento 1 Tietokonejärjestelmän rakenne. Järjestelmän eri tasot Laitteiston nopeus

Algoritmit 1. Luento 11 Ti Timo Männikkö

Luento 1 Tietokonejärjestelmän rakenne

Kertausluento 1 (lu01, lu02, lu03) Tietokonejärjestelmän rakenne ttk-91 ja sillä ohjelmointi

Tietokoneen toiminta, Kevät Copyright Teemu Kerola Järjestelmän eri tasot Laitteiston nopeus

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin perusteet Y Python

VALO-ohjelmat ja LTSP kouluissa. Elias Aarnio Innopark, AVO-hanke

Luento 1 Tietokonejärjestelmän rakenne. Järjestelmän eri tasot Laitteiston nopeus

Luku 7. Verkkoalgoritmit. 7.1 Määritelmiä

n! k!(n k)! n = Binomikerroin voidaan laskea pelkästään yhteenlaskun avulla käyttäen allaolevia ns. palautuskaavoja.

Tietotyypit ja operaattorit

Matriiseista. Emmi Koljonen

A B = (1, q, q 2 ) (2, 0, 2) = 2 2q q 2 = 0 q 2 = 1 q = ±1 A(±1) = (1, ±1, 1) A(1) A( 1) = (1, 1, 1) (1, 1, 1) = A( 1) A(1) A( 1) = 1

Harjoitustyö: virtuaalikone

Ohjelmoinnin perusteet Y Python

Tietokoneen rakenne: Harjoitustyö. Motorola MC prosessori

Ohjelmassa muuttujalla on nimi ja arvo. Kääntäjä ja linkkeri varaavat muistilohkon, jonne muuttujan arvo talletetaan.

Numeeriset menetelmät

3 Lineaariset yhtälöryhmät ja Gaussin eliminointimenetelmä

Graafit ja verkot. Joukko solmuja ja joukko järjestämättömiä solmupareja. eli haaroja. Joukko solmuja ja joukko järjestettyjä solmupareja eli kaaria

DXL Library ja DXL-kielen olemus. Pekka Mäkinen SoftQA Oy http/

MATEMATIIKKA. Matematiikkaa pintakäsittelijöille. Ongelmanratkaisu. Isto Jokinen 2017

Ohjelmoinnin perusteet Y Python

2. Lisää Java-ohjelmoinnin alkeita. Muuttuja ja viittausmuuttuja (1/4) Muuttuja ja viittausmuuttuja (2/4)

Tietorakenteet ja algoritmit

4. Lausekielinen ohjelmointi 4.1

811312A Tietorakenteet ja algoritmit, , Harjoitus 3, Ratkaisu

System.out.printf("%d / %d = %.2f%n", ekaluku, tokaluku, osamaara);

Algoritmit 1. Luento 1 Ti Timo Männikkö

Laitteistonläheinen ohjelmointi

Sisällys. 6. Muuttujat ja Java. Muuttujien nimeäminen. Muuttujien nimeäminen. salinovi tai syntymapaiva

Transkriptio:

1

Datan rinnakkaistamisessa siis eri prosessointiyksiköt suorittavat saman operaation annetulle datalle, joka pilkotaan prosessointiyksikköjen kesken. Pointti on siis se, että kyseessä ei ole tehtävien rinnakkaistaminen (kuten usein puhuttaessa rinnakkaisuudessa), vaan jokainen prosessointiyksikkö suorittaa saman koodin samanaikaisesti, jolloin datan käsittelyyn saadaan huomattava nopeuslisä. Varsinainen ohjelma voi siis olla yksisäikeinen ja saada silti huomattavan nopeuslisän. Moderneissa grafiikkakorteissa hyödynnetään myös samanlaista toimintamallia 2

3DNow!:n tuki on nykyään lähes loppunut -> ei välttämättä enää löydy tulevaisuuden suorittimista esim. SSE4.2 tuo operaatiot CRC32-summan laskemiseen. SSE4A on AMD:n oma laajennos ja ei ole saatavilla Intelin suorittimissa SSE:n käytössä on olennaista huomioida, että uusin päivitys ei välttämättä ratkaise kaikkia ongelmia. Ei siis kannata ajatella, että otetaan SSE4 käyttöön ja ongelma ratkeaa, koska kaikki SSE2:n jälkeen tulleet versiot ovat suurimmaksi osin käskylaajennoksia ja moni ongelma voi silti olla sellainen, että sen ratkaisemiseen ei tarvitse (tai edes pysty) käyttämään SSE tai SSE2:ta uudempaa tekniikkaa. AVX (Advanced Vector Extensions) on uusi tekniikka ja tulee korvaamaan nykyiset SSEtekniikat, eli SSE tekniikkana on kehityksen/yleistymisen puolesta enemmänkin kallistumassa ehtoopuolelle. AVX:ssä on kuitenki tuki vanhoille SSE-operaatioille, jota toimivat AVX:n rekisterien alemmassa 128 bitissä. AVX Vaatii suhteellisen uuden käyttöjärjestelmän toimiakseen, esim. Windows 7 SP1. AVX:n tarjoama uusi ohjelmointitapa mahdollistaa mm. kahdelle rekisterille tehtävän operaation tuloksen tallentamisen kolmanteen rekisteriin, mikä ei ole ollut aiemmissa tekniikoissa mahdollista. Etuna tässä on, että operaation tulos ei ylikirjoita toisen parametri rekisterin alkuarvoa, kuten aiemmissa tekniikoissa tapahtuu (esim. ennen a = a+b, mutta uudessa c = a+b). 3

Vaikea löytää mitään kunnollista mainospuhetta, koska tekniikka (SIMD/SSE) jo tavallaan mainostaa itse itseään Erityistä hyötyä on kuitenkin mahdollista saada sovelluksissa, jotka käsittelevät suuria datamääriä. Yksittäisten lukujen tapauksessa SSE:n käyttö ei maksa vaivaa, koska tekniikan ajatuksena on nimenomaan ladata paljon dataa ja tehdä sille operaatioita Ohjelman nopeutumiseen SSE:n avulla vaikuttaa tietenkin myös moni muu tekijä, esimerkiksi miten ohjelma on yleisesti ottaen rakennettu ja millainen algoritmi on kyseessä Sovelluskohteet on otettu Intelin näkemyksen perusteella. Näissä kaikissa on nähtävissä samankaltaisuus siinä mielessä, että tiettyä operaatiota tehdään isolle datajoukolle. 4

Tässä siis joitain esimerkkejä, joissa on käytetty SSE-optimointeja Peleissä yleisesti, mutta tässä esimerkkinä Doom3, koska sen lähdekoodit ovat saatavilla ja niistä näkee, että esim. vektori- ja matriisilaskuissa sekä äänen prosessoinnissa on käytetty SSE:tä MS:n DirectX/Direct3D tunnistaa ajonaikaisesti onko SSE:tä mahdollista käyttää Qt:ssa käytetään SSE:tä piirtorutiinien optimointiin ja ainakin on tehty tutkimusta merkkijono-operaatioiden nopeuttamisen osalta VLC-soittimessa SSE:tä käytetään ainakin puskurien kopioinnin nopeuttamiseen Yleisesti ottaen voidaan todeta, että SSE:tä käytetään paljon erilaisissa multimediasovelluksissa ja sovellusalueissa 5

MXCSR rekisteri sisältää tietoa liukulukuoperaatioista, mm. poikkeukset ja pyöristysten kontrollointi Jokaista SSE:n rekisteriä (XMMn) voi käsitellä erikseen 32 bittiset luvut pakataan 128 bittiseen rekisteriin omiin lokeroihinsa. Kaikkien neljän skalaarin käsittely tapahtuu PS-päätteisillä käskyillä (Packed Scalar) SSE:ssä on myös käskyjä (SS-päätteiset Single Scalar), joilla voidaan käsitellä yksittäisiä skalaareja. Tällöin käsitellään XMMn-rekisterin 32 alinta bittiä ja operaatio ei vaikuta kolmeen ylempään skalaariin. 6

SSE2:n tuomissa käskyissä rekisteri voi sisältää 2 64bit kokonaislukua, 4 32bit kokonaislukua, 8 16bit kokonaislukua, 16 8bit kokonaislukua tai 2 64bit liukulukua. SSE:n tuoma tuki 32bit liukuluvuille on toki edelleen voimassa. Kaikille datatyypeille (kokonaisluku/liukuluku) on omat erilliset käskynsä. SSE2:n myötä päästiin eroon SSE:n ja MMX:n sekakäytöstä. Myöhemmät SSE-versiot eivät tuoneet muuta, kuin joukon uusia käskyjä, joten SSE2:n esittelemä datankäsittelymalli on edelleen voimassa. Loppukommenttina mainitaan, että SSE tarvitsee tuen käyttöjärjestelmältä. Tuki vaaditaan, jotta prosessorin tila osataan tallentaa oikein esimerkiksi ohjelmasta toiseen siirryttäessä, millä vältetään mm. datan korruptoituminen ja hukkuminen. Käytännössä tuki SSE:lle on kaikissa moderneissa käyttöjärjestelmissä, mutta esimerkiksi aiemmin mainitun AVX:n tapauksessa tuki on vasta Windows 7 SP1:stä alkaen. 7

Assemblyllä ohjelmoidessa voi lähdemateriaaliksi ottaa esimerkiksi Intelin SSE-speksin, jossa kaikki käskyt on kerrottu. Ongelmana kuitenkin on, että esim. visual studio ei salli inline assemblyn käyttöä 64bit ohjelmissa. Suositellumpi tapa on käyttää kääntäjän intrinsic-funktioita, jotka on yleensä kuvattu kääntäjän dokumentaatiossa. Ongelmana voi kuitenkin olla eroavaisuudet eri kääntäjien välillä. Kääntäjän vektorointitoiminnoilla vältytään itse kirjoittamasta SSE-koodia. Ajatuksena on, että kääntäjä pyrkii tuottamaan tavallisesta koodista SIMD-periaatteita noudattavaa koodia. Vektorointitoiminnon saa moderneista kääntäjistä käyttöön tietyillä vivuilla, jotka on kuvattu kääntäjän dokumentaatiossa. Ongelma kuitenkin on, että lopputuloksen laatu on täysin kääntäjän päätettävissä ja erityisesti tässä on suuria eroja kääntäjien välillä. Intelin oma kääntäjä tekee useimmiten parasta jälkeä. Joka tapauksessa kääntäjän valmiilla toiminnoilla voi kuitenkin saada pientä nopeuslisää ohjelmaan. 8

Muuttujat näkyvät käyttäjälle ikään kuin unionina, eli 128bit muuttujan eri kohtiin on mahdollisuus päästä käsiksi. Tätä ei kuitenkaan suositella. Kääntäjän tarjoamat intrinsic-funktiot löytyvät parhaiten kääntäjän dokumentaatiosta Esimerkissä (_mm_mul_ps) ps tarkoittaa packed scalar, eli operaatio suoritetaan 128bit muuttujille, joihin on pakattu neljä 32bit liukulukua, ts. saadaan laskettua neljän floatin yhtäaikainen kertolasku Useat liukulukuja käsittelevistä intrinsic-funktioista on nimetty suoraan assemblykäskyjen perusteella, mutta tämä ei päde esim. joidenkin vertailufunktioiden osalta. Kokonaislukujen osalta assembly-käskyt eivät täysin vastaa intrinsic-funktioiden nimeämistä (esim. PADDD -> _mm_add_epi32) Tässäkin ohjelmointitavassa toimitaan hyvin lähellä laitteistotasoa, koska intrinsicfunktiot on mapattu suoraan vastaaviin assembly-käskyihin. Ohjelmointi muistuttaa aika paljon assembly-ohjelmointia, eli annetaan käsky ja operandit, jonka jälkeen saadaan tulos tiettyyn paikkaan. Lisäksi tarvitaan osaamista bittien pyörittelystä, koska monet käskyt ottavat myös bittimaskin, jonka perusteella asioita tehdään. Tästä tulee esimerkkiä myöhemmin. 9

Tässä siis yksinkertainen esimerkki kokonaislukutaulukon nollaamisesta. Ensimmäiseksi ihan tavallinen C++-toteutus vertailun vuoksi. Jälkimmäisessä SSE-toteutus, jossa ensimmäiseksi castataan uusi SSE-tyyppinen kokonaislukuosoitin alkuperäiseen int-taulukkoon Koska int on 32 bittinen ja SSE:n rekisterit ovat 128 bittisiä, voidaan silmukassa käsitellä neljä 32bit kokonaislukua samaan aikaan _mm_setzero_si128-funktio luo uuden m128i muuttujan, jonka kaikki komponentit ovat nollia. _mm_store_si128- funktio sijoittaa muuttujan taulukkoon buf-osoittimen määräämään paikkaan. 10

Tässä siis yksinkertainen esimerkki, miten pistetulo voidaan laskea yhdellä käskyllä - _mm_dp_ps. Vaatii siis SSE4.1-tuen. _mm_dp_ps on 32 bittisille liukuluvuille, _mm_dp_pd on 64 bittisille _mm_set_ps-käskyllä saadaan luotua uusi 128bit muuttuja, joka sisältää neljä 32bit liukulukua. Jos haluttaisiin luoda vektori, jonka kaikilla komponenteilla on sama arvo, voitaisiin käyttää _mm_set1_ps-käskyä. _mm_dp_ps:n viimeisenä parametrina oleva vakio on maski, joka kuvaa mitkä komponentit laskettavista vektoreista ovat mukana laskussa ja mihin komponentteihin laskun tulos sijoitetaan tulosvektorissa. Maskin bitit 0-3 kuvaavat mihin komponentteihin tulosvektorissa pistetulon arvo laitetaan (sama arvo sijoitetaan kaikkiin valittuihin) Bitit 4-7 kuvaavat mitkä komponentit lähdevektoreista ovat laskussa mukana. 0xE1 = 1110 0001, eli lähdevektoreista valitaan komponentit 2, 3 ja 4 laskettavaksi ja pistetulon tulos sijoitetaan tulosvektorin ensimmäiseen komponenttiin 11

AltiVec on siis PowerPC:n vastaava SIMD-tekniikka. AltiVec tuo 32 128bittistä rekisteriä ja tekniikka tukee kokonaislukujen (8-32bit) sekä 32bit liukulukujen laskemista. AltiVec:n RGB-tietotyyppi on erityinen tietotyyppi pikselien käsittelyyn. Yksi tietotyyppi sisältää 8 16bit pikseliä muodossa 1/5/5/5. Vastaavaa tietotyyppiä ei ole SSE:ssä. AltiVec:ssä ei voida siirtää dataa tavallisten CPU-rekisterien ja vektorirekisterien välillä, ts. kaikki näiden välillä liikuteltava data on kierrätettävä muistin kautta. SSE:ssä tällaista rajoitusta ei ole, mutta asia on myös x86:sta tuttu x87:n (FPU) käsittelyn osalta. Ohjelmoitaessa C/C++:lla AltiVec tarjoaa erityisen vector-avainsanan, jolla voidaan muodostaa helposti uusia vektorimuuttujia. Esim vector int i; luo uuden 128bit muuttujan, joka sisältää 4 32bit kokonaislukua. Vastaavaa mahdollisuutta ei ole SSE:ssä. Toisaalta vector-avainsanan käyttö aiheuttaa ongelmia STL:n vectorin kanssa, vaikka tähän tosin on esim. GCC:ssä olemassa kiertotie. Edelleen vector-avainsana mahdollistaa normaalien aritmeettisten ja binäärioperaatioiden tekemisen C/C++-koodissa, mikä on luonnollisesti mielekkäämpää ohjelmoijan kannalta. SSE ei tällaista toimintaa tue, joten aina on käytettävä kääntäjän intrinsic-funktioita. Lopussa on linkki eräässä yliopistossa tehtyyn tutkimukseen SSE:n ja AltiVec:n välillä lähinnä nopeuden osalta. Yhteenvedossa todetaan, että vaikka AltiVec on huomattavasti kypsempi ja ohjelmoijaystävällisempi, SSE on kuitenkin mennyt nopeudessa selkeästi ohi. 12

Tässä siis joitain huomioonotettavia asioita ja jopa haasteita SSE:n käytössä Luonnollisestikaan tekniikka ei sovellu kaikkeen mahdolliseen käyttöön. Esimerkiksi jonkin järjestelyalgoritmin toteuttaminen voi olla haastavaa, vaikka joitain toteutuksia näiltä osin on tehty. Kääntäjissä on eroja luonnollisesi tuotetun koodin laadun osalta (Intelin kääntäjä on yleensä paras), mutta myös kääntäjän tarjoaman tuen osalta. Esimerkiksi GCC:ssä on tavallisten SSE intrinsic-funktioiden lisäksi omat ja hieman erilaiset toteutukset SSE:n käyttöön, joten tällaisia toteutuksia käytettäessä tehdään helposti kääntäjäriippuvaista koodia. Tuotettu koodi on tietenkin x86/x64 riippuvaista, joten muille arkkitehtuureille joudutaan tekemään omat vastaavat toteutukset tai muut ratkaisut. Lisäksi on huomioitava, että kaikkia SSE-versioita ei ole välttämättä saatavilla kaikissa koneissa, joten tällaiseenkin tilanteeseen on varauduttava. Monet SSE:n käskyt vaativat, että käsiteltävä data on jaksotettu 16 tavun pätkiin. Yhtenä esimerkkinä tästä on tavallisen taulukon käsittely SSE:n avulla. Koska SSE lataa muistista käsiteltäväksi aina 16 tavua kerrallaan, on huolehdittava, että alkuperäisen taulukon koko menee tavumäärällisesti tasan 16:lla jaettuna. Tämä vaatimus voi luonnollisesti aiheuttaa lisätyötä, jos käsiteltävä data ei luonnostaan ole halutunlaisesti jaksotettua. Kaikissa SSE:n käskyissä tätä vaatimusta ei ole, mutta yleensä suoritus on nopeampaa, jos data on 16 tavun jaksoissa. SSE:n tehokas hyödyntäminen vaatii usein manuaalista työtä ja välttämättä koodin muuttaminen SSE-käskykannalle ei ole järin yksinkertaista, joten voi olla syytä miettiä, 13

maksaako optimointi vaivan. Kääntäjien vektorointiominaisuuksia kannattaa tietenkin hyödyntää, mutta tuloksen laadussa on suuria eroja kääntäjien välillä ja usein tulos ei kuitenkaan ole niin tehokas kuin ohjelmoijan kirjoittamana (ainakaan taitavan ohjelmoijan). Viimeisenä seikkana on liukulukulaskujen tarkkuuserot x87:n ja SSE:n välillä. Pointti on siinä, että x87 pitää liukulukulaskujen välitulokset 80 bittisinä, mutta SSE:n tarkin liukulukutarkkuus on 64 bittiä. Tästä voi aiheutua tarkkuuseroja tuloksissa SSEoptimointien jälkeen, millä voi olla merkitystä esimerkiksi jossain tieteellisessä laskennassa. 13

Tässä joitain hyödyllisiä linkkejä, jos aihe alkaa kiinnostamaan. Luonnollisesti Google tarjoaa lisää. 14