Vektoriprosessori - Vector processor
In computing , joka on vektori prosessori tai joukko prosessori on keskusyksikkö (CPU), joka toteuttaa käskykannan jossa sen ohjeet on suunniteltu toimimaan tehokkaasti suurten yksiulotteiset matriisit tietojen kutsutaan vektoreita . Tämä on toisin kuin skalaari-prosessorit , jonka ohjeet toimivat yhdessä datakohteet ainoastaan, ja toisin kuin jotkut näiden samojen skalaari-prosessorit, joilla on ylimääräisiä SIMD tai Sw Aritmeettinen yksikköä. Vektoriprosessorit voivat parantaa huomattavasti suorituskykyä tietyissä työmäärissä, erityisesti numeerisessa simulaatiossa ja vastaavissa tehtävissä. Vektorin käsittelytekniikat toimivat myös videopelikonsolin laitteistossa ja grafiikan kiihdyttimissä .
Vektorikoneet ilmestyivät 1970 -luvun alussa ja hallitsivat supertietokoneiden suunnittelua 1970 -luvulta 1990 -luvulle, erityisesti eri Cray -alustoja. Perinteisten mikroprosessorimallien hinta-laatusuhteen nopea lasku johti vektorisupertietokoneen kuolemaan 1990-luvun lopulla.
Historia
Aikainen työ
Vektorinkäsittelyn kehittäminen alkoi 1960 -luvun alussa Westinghousessa heidän "Solomon" -projektissaan. Salomon tavoitteena oli kasvattaa dramaattisesti matematiikka suorituskykyä käyttämällä useita yksinkertaisia matemaattisia apuprosessoreita valvonnassa yksi isäntä suorittimen . Suoritin syötti yhden yhteisen käskyn kaikille aritmeettisille logiikkayksiköille (ALU), yhden sykliä kohden, mutta jokaisella eri datapisteellä. Tämä salli Salomon -koneen soveltaa yhtä algoritmia suureen tietojoukkoon , joka syötettiin taulukon muodossa.
Vuonna 1962 Westinghouse peruutti projektin, mutta ponnistelut aloitettiin uudelleen Illinoisin yliopistossa nimellä ILLIAC IV . Heidän versionsa suunnittelusta vaati alun perin 1 GFLOPS -konetta, jossa oli 256 ALU: ta, mutta kun se lopulta toimitettiin vuonna 1972, sillä oli vain 64 ALU: ta ja se voi saavuttaa vain 100-150 MFLOPS. Siitä huolimatta se osoitti, että peruskonsepti oli hyvä, ja kun sitä käytettiin tietointensiivisissä sovelluksissa, kuten laskennallisen nesteen dynamiikassa , ILLIAC oli maailman nopein kone. ILLIAC -lähestymistapa käyttää erillisiä ALU: ita kullekin tietoelementille ei ole yleinen myöhemmille suunnitelmille, ja siihen viitataan usein erillisessä luokassa, massiivisesti rinnakkaislaskennassa . Noin tähän aikaan Flynn luokitteli tämän tyyppisen käsittelyn SIMT: n varhaiseksi muotoksi .
Tietokone operaatioiden toimintoja on esitetty ja kehittänyt Kartsev 1967.
Supertietokoneet
Vektorinkäsittelyn ensimmäinen onnistunut toteutus tapahtui vuonna 1966, jolloin otettiin käyttöön sekä Control Data Corporation STAR-100 että Texas Instruments Advanced Scientific Computer (ASC).
Perus -ASC (eli "yksi putki") ALU käytti putkilinjaarkkitehtuuria, joka tuki sekä skalaari- että vektorilaskentaa, ja huipputeho saavutti noin 20 MFLOPS, joka saavutettiin helposti käsiteltäessä pitkiä vektoreita. Laajennetut ALU -kokoonpanot tukivat "kahta putkea" tai "neljää putkea" vastaavalla 2X tai 4X suorituskyvyn vahvistuksella. Muistin kaistanleveys riitti tukemaan näitä laajennettuja tiloja.
STAR-100 oli muuten hitaampi kuin CDC: n omat supertietokoneet, kuten CDC 7600 , mutta dataan liittyvissä tehtävissä ne pystyivät pysymään perässä samalla kun ne olivat paljon pienempiä ja halvempia. Kone kuitenkin vei myös paljon aikaa vektori -ohjeiden dekoodaamiseen ja prosessin valmisteluun, joten se vaati hyvin erityisiä tietojoukkoja, ennen kuin se todella nopeutti mitään.
Vektoritekniikkaa hyödynnettiin ensimmäisen kerran vuonna 1976 kuuluisalla Cray-1: llä . Sen sijaan, että tiedot jätettäisiin muistiin, kuten STAR-100 ja ASC, Cray-mallissa oli kahdeksan vektorirekisteriä , jotka sisälsivät kuusikymmentäneljä 64-bittistä sanaa. Vektori -ohjeita käytettiin rekisterien välillä, mikä on paljon nopeampaa kuin päämuistille puhuminen. Vaikka STAR-100 soveltaa yhtä operaatiota muistissa olevan pitkän vektorin yli ja siirtyy sitten seuraavaan operaatioon, Cray-malli lataa pienemmän osan vektorista rekistereihin ja soveltaa sitten niin monta toimintoa kuin mahdollista näihin tietoihin , jolloin vältetään monia paljon hitaampia muistin käyttöoperaatioita.
Cray -suunnittelu käytti putkilinjan rinnakkaisuutta vektori -ohjeiden toteuttamiseen useiden ALU: iden sijaan. Lisäksi suunnittelussa oli täysin erilliset putkistot eri ohjeille, esimerkiksi lisäys/vähennys toteutettiin eri laitteistoissa kuin kertominen. Tämä mahdollisti erän vektori -käskyjen liittämisen kuhunkin ALU -alayksikköön, tekniikkaa, jota he kutsuivat vektoriketjuksi . Cray-1: n suorituskyky oli yleensä noin 80 MFLOPS, mutta jopa kolmen ketjun ollessa käynnissä se voi saavuttaa huippunsa 240 MFLOPS: n nopeudella ja keskimäärin noin 150-paljon nopeammin kuin mikään aikakauden kone.
Muut esimerkit seurasivat. Control Data Corporation yritti palata uudelleen huippuluokan markkinoille ETA-10- koneellaan, mutta se myi huonosti, ja he pitivät sitä mahdollisuutena jättää supertietokoneala kokonaan. Varhaisessa ja 1980-luvun puolivälissä japanilaisten yritysten ( Fujitsu , Hitachi ja Nippon Electric Corporation (NEC) esitteli rekisteri-pohjainen vektori koneita samanlainen Cray-1, tyypillisesti hieman nopeammin ja paljon pienempi. Oregon -pohjainen Floating Point Systems (FPS) rakensi lisäsuorittimia minitietokoneille ja rakensi myöhemmin omia minitietokoneitaan .
Koko ajan Cray oli suorituskyvyn johtaja ja voitti jatkuvasti kilpailua sarjan koneilla, jotka johtivat Cray-2 , Cray X-MP ja Cray Y-MP . Sittemmin supertietokoneiden markkinat ovat keskittyneet paljon enemmän massiiviseen rinnakkaiskäsittelyyn kuin vektoriprosessorien parempiin toteutuksiin. Kuitenkin tunnustamalla vektorinkäsittelyn edut IBM kehitti virtuaalisen vektoriarkkitehtuurin käytettäväksi supertietokoneissa, jotka yhdistävät useita skalaarisia prosessoreita toimimaan vektoriprosessorina.
Vaikka Cray-1: tä muistuttavat vektorisupertietokoneet ovat nykyään vähemmän suosittuja, NEC on jatkanut tämän tyyppisten tietokoneiden valmistamista tähän päivään asti SX-sarjan tietokoneillaan. Viimeksi SX-Aurora TSUBASA sijoittaa suorittimen ja joko 24 tai 48 gigatavun muistin HBM 2 -moduuliin kortille, joka muistuttaa fyysisesti grafiikan rinnakkaisprosessoria, mutta se ei toimi rinnakkaisprosessorina, vaan se on pääkone PC-yhteensopiva tietokone, johon se on liitetty, palvelee tukitoimintoja.
Eräs äärimmäinen ja harvinainen esimerkki array-prosessorista oli Aspex Microelectronics ASP, joka luokitteli itsensä "massiiviseksi laajaksi SIMD: ksi", mutta jolla oli bittitason ALU: t ja bittitason ennustus, joten sitä voitaisiin lopullisesti pitää Array (Vector) -prosessorina. Vuonna 2010 julkaistu Linedancer sisälsi 4096 2-bittistä Predicated SIMD ALU -yksikköä, joista jokaisella oli oma sisältöosoitteinen muisti , ja se kykeni 800 miljardiin käskyyn sekunnissa. Mielenkiintoista on, että Flynnin taksonomian mukaan ASP oli sekä assosiatiivinen prosessori että matriisiprosessori.
GPU
Nykyaikaiset grafiikkaprosessointiyksiköt ( GPU ) sisältävät joukon varjostinputkia, joita voidaan käyttää laskentaytimillä , ja niitä voidaan pitää vektoriprosessoreina (käyttäen samanlaista strategiaa muistin viiveiden piilottamiseen). Kuten Flynnin vuoden 1972 asiakirjassa esitetään, SIMT-pohjaisten grafiikkasuorittimien keskeinen erottava tekijä on se, että sillä on yksi käskyn dekooderilähetin, mutta että saman käskyn vastaanottavat ja suorittavat ytimet ovat muuten kohtuullisen normaaleja: omat ALU: t, omat rekisteritiedostot, omat Load/Store -yksiköt ja omat riippumattomat L1 -tietovälimuistinsa. Näin ollen vaikka kaikki ytimet suorittavat samanaikaisesti täsmälleen saman käskyn lukitusvaiheessa keskenään, he tekevät sen täysin eri datalla täysin eri muistipaikoista. Tämä on huomattavasti monimutkaisempaa ja osallisempaa kuin "pakattu SIMD" , joka rajoittuu tiukasti vain rinnakkaisten liukuhihnojen aritmeettisten toimintojen suorittamiseen. Vaikka nykyisten kaupallisten grafiikkasuorittimien tarkat sisäiset yksityiskohdat ovat yksityisiä salaisuuksia, MIAOW -tiimi pystyi koottamaan yhteen anekdoottisia tietoja, jotka ovat riittäviä toteuttamaan AMDGPU -arkkitehtuurin osajoukko.
Vertailu moderniin arkkitehtuuriin
Vuodesta 2016 lähtien useimmat hyödyke-suorittimet toteuttavat arkkitehtuureja, joissa on kiinteän pituiset SIMD- ohjeet. Ensimmäisessä tarkastuksessa näitä voidaan pitää eräänlaisena vektorinkäsittelymuotona, koska ne toimivat useilla (vektorisoiduilla, nimenomaisen pituisilla) tietojoukoilla ja lainaavat ominaisuuksia vektoriprosessoreilta. Kuitenkin määritelmän lisäämällä SIMD ei itse tee prosessori kuin todellinen vector Prosessori koska SIMD on samanpituisia ja vektorit ovat vaihtelevia. Ero kuvataan alla esimerkeillä, joissa esitetään ja verrataan kolmea luokkaa: Pure SIMD, Predicated SIMD ja Pure Vector Processing.
- Puhdas (kiinteä) SIMD - tunnetaan myös nimellä "pakattu SIMD", SIMD rekisterissä (SWAR) ja Pipelined -prosessori Flynnin taksonomiassa. Yleisiä esimerkkejä SIMD: n käyttämisestä Vector -prosessorien innoittamilla ominaisuuksilla ovat Intel x86: n MMX- , SSE- ja AVX -ohjeet sekä AMD: n 3DNow! laajennukset, ARM NEON , Sparcin VIS -laajennus, PowerPC : n AltiVec ja MIPS MSA . Vuonna 2000 IBM , Toshiba ja Sony loivat yhdessä Cell -prosessorin , joka on myös SIMD .
- Predicated SIMD - tunnetaan myös nimellä Associative Processing . Kaksi merkittävää esimerkkiä, joissa on elementtikohtainen ( kaistapohjainen ) ennakointi, ovat ARM SVE2 ja AVX-512
- Puhtaat vektorit- kuten luokiteltu Duncanin taksonomiassa- näihin kuuluvat alkuperäiset Cray-1 , RISC-V RVV ja SX-Aurora TSUBASA . Vaikka muistipohjainen STAR-100 oli myös vektoriprosessori.
Muut CPU malleja ovat joitakin useita ohjeita vektori käsittely useita (vektoroitu) aineistoja, tunnetaan tyypillisesti MIMD ( M ultiple I nstruction, M ultiple D ata) ja toteutettu VLIW ( V ery- L Ong I nstruction W ord). Fujitsu FR-V VLIW / vektori prosessori yhdistää molempia tekniikoita.
Ero SIMD: n ja Vector -prosessorin välillä.
SIMD -käskysarjoilla ei ole olennaisia ominaisuuksia verrattuna vektoriprosessorin käskysarjoihin. Tärkein näistä on se, että vektoriprosessorit ovat luonteeltaan ja suunnittelultaan luonteeltaan aina vaihtelevan pituisia alusta asti.
Jos puhdasta (kiinteää leveyttä, ei ennakointia) SIMD: tä väitetään yleensä virheellisesti olevan "vektoreita" (koska SIMD: tä käytetään käsittelemään tietoja, jotka sattuvat olemaan vektoreita), analysoimalla ja vertaamalla historiallisia ja nykyaikaisia ISA: ita, varsinaiset vektoriprosessorit voivat sillä on seuraavat ominaisuudet, joita ei ole SIMD ISA: ssa:
- tapa asettaa vektorin pituus (kuten
setvlohje RISCV RVV: ssä) tai tarjotaREP(käskyn toisto) -ominaisuus jossain muodossa rajoittamatta toistoja kahden potenssiin - Iteraation ja vähentäminen yli elementtien sisällä Vektorit. Versiosta 0.10 alkaen RISC-V-vektoreissa on vain pelkistys, kun taas SX-Aurora- ja uudemmissa Cray-järjestelmissä on iterointi ja vähennys.
Predicated SIMD (osa Flynnin taksonomiaa ), joka on kattava yksittäinen elementtitasoinen predikaattimaski jokaisessa vektorikäskyssä, kuten nyt ARM SVE2: ssa. ja AVX-512 , melkein vektori-prosessori. Ennalta määritetty SIMD käyttää kiinteän leveyden SIMD ALU -yksiköitä, mutta mahdollistaa yksiköiden paikallisesti ohjatun (ennakoidun) aktivoinnin, jotta saadaan aikaan vaihtelevan pituiset vektorit. Alla olevat esimerkit auttavat selittämään nämä kategoriset erot.
Koska SIMD on kiinteäleveinen eräkäsittely, se ei rakenteeltaan kykene käsittelemään iterointia ja pienentämistä. Tätä kuvataan edelleen alla olevilla esimerkeillä.
Lisäksi vektoriprosessorit voivat olla resurssitehokkaampia (käyttävät hitaampaa laitteistoa, säästävät virtaa, mutta saavuttavat silti suorituskyvyn) ja niillä on vähemmän viiveitä kuin SIMD: llä vektoriketjutuksen avulla .
Harkitse sekä SIMD-prosessoria että vektoriprosessoria, jotka käsittelevät 4 64-bittistä elementtiä ja suorittavat LOAD-, ADD-, MULTIPLY- ja STORE-sekvenssit. Jos SIMD -leveys on 4, SIMD -prosessorin on LATAA 4 elementtiä kokonaan, ennen kuin se voi siirtyä ADD -tiedostoihin, sen on suoritettava kaikki ADD: t ennen kuin se voi siirtyä MULTIPLY -yksiköihin, ja samoin on suoritettava kaikki MULTIPLY -yksiköt ennen kuin se voi käynnistä kaupat. Tämä on määritelmän ja suunnittelun mukaan .
Neljän leveän samanaikaisen 64-bittisen LOADin ja 64-bittisen TALLENNUKSEN suorittaminen on kalliita laitteistossa (256-bittiset datapolut muistiin). 4x 64 -bittinen ALU, erityisesti MULTIPLY, samoin. Näiden korkeiden kustannusten välttämiseksi SIMD-prosessorilla on oltava 1 leveä 64-bittinen LOAD, 1 leveä 64-bittinen STORE ja vain 2 leveä 64-bittinen ALU. Kuten on esitetty kaaviossa, jossa oletetaan usean ongelman suoritusmalli , seurauksena on, että toimintojen suorittaminen kestää nyt kauemmin. Jos usean numeron julkaiseminen ei ole mahdollista, toiminnot kestävät vielä kauemmin, koska LD: ää ei ehkä myönnetä (käynnistetä) samanaikaisesti kuin ensimmäiset ADD: t jne. Jos 64-bittisiä SIMD-ALU- alustoja on vain 4 leveää, valmistumisaika on vieläkin huonompi: SIMD-toiminnot voivat alkaa vasta, kun kaikki neljä LOAD-laitetta on suoritettu, ja STORE-toiminnot voidaan aloittaa vasta, kun kaikki ALU-toiminnot on suoritettu.
Vektoriprosessori sitä vastoin, vaikka se olisi yksi ongelma eikä käytä SIMD ALU: ita, sillä on vain 1 leveä 64-bittinen LOAD, 1 leveä 64-bittinen STORE (ja kuten Cray-1: llä , kyky suorittaa MULTIPLY samanaikaisesti ADD: n kanssa), saattaa suorittaa neljä toimintoa nopeammin kuin SIMD-prosessori, jossa on 1 leveä LOAD, 1 leveä STORE ja 2 leveä SIMD. Tämä resurssien tehokkaampi hyödyntäminen vektoriketjujen ansiosta on keskeinen etu ja ero SIMD: hen verrattuna. Suunnittelunsa ja määritelmänsä mukaisesti SIMD ei voi ketjuttaa muuta kuin koko tulosryhmää.
Kuvaus
Yleisesti ottaen CPU: t voivat käsitellä yhtä tai kahta dataa kerrallaan. Esimerkiksi useimmissa suorittimissa on ohje, joka sanoo olennaisesti "lisää A B: hen ja laita tulos C: hen". A-, B- ja C -tiedot voitaisiin ainakin teoriassa koodata suoraan ohjeeseen. Tehokkaassa toteutuksessa asiat ovat kuitenkin harvoin näin yksinkertaisia. Tiedot lähetetään harvoin raakamuodossa, ja ne "osoittavat" sen sijaan lähettämällä osoitteen tietoja sisältävään muistipaikkaan. Tämän osoitteen dekoodaus ja tietojen saaminen muistista kestää jonkin aikaa, jonka aikana CPU perinteisesti istui käyttämättömänä odottaen pyydettyjen tietojen ilmestymistä. Suorittimen nopeuden kasvaessa tästä muistin viiveestä on historiallisesti tullut suuri suorituskyvyn este; katso Muistiseinä .
Näiden vaiheiden kuluttaman ajan vähentämiseksi useimmat nykyaikaiset suorittimet käyttävät tekniikkaa, joka tunnetaan nimellä käskyputki , jossa ohjeet kulkevat vuorotellen useiden alayksiköiden läpi. Ensimmäinen alayksikkö lukee osoitteen ja purkaa sen, seuraava "hakee" näiden osoitteiden arvot ja seuraava laskee itse. Pipelinoinnissa "temppu" on aloittaa seuraavan käskyn dekoodaus jo ennen kuin ensimmäinen on poistunut suorittimesta kokoonpanolinjan tapaan , joten osoitekooderi on jatkuvasti käytössä. Minkä tahansa tietyn käskyn suorittaminen vie saman ajan, eli viive , mutta CPU voi käsitellä koko erän toimintoja päällekkäin paljon nopeammin ja tehokkaammin kuin jos se tekisi sen yksi kerrallaan.
Vektoriprosessorit vievät tämän käsitteen askeleen pidemmälle. Pelkien ohjeiden liittämisen sijasta ne myös yhdisttävät itse tiedot. Prosessorille syötetään ohjeita, joissa sanotaan, että ei vain lisätä A: ta B: hen, vaan lisätä kaikki numerot "täältä tänne" kaikkiin numeroihin "sieltä sinne". Sen sijaan, että jatkuvasti tarvitse purkaa ohjeet ja sitten hakea tarvittavat tiedot niiden loppuun saattaminen, prosessori lukee yksi käsky muistista, ja se on yksinkertaisesti hiljaista määritelmässä käskyn itse että käsky toimii jälleen toisen kohteen tietoja, osoitteessa yksi askel suurempi kuin edellinen. Tämä mahdollistaa merkittäviä säästöjä dekoodausajassa.
Havainnollistaaksemme, mitä eroa tällä voi olla, harkitse yksinkertaista tehtävää lisätä kaksi 10 numeron ryhmää yhteen. Normaalilla ohjelmointikielellä kirjoitettaisiin "silmukka", joka poimisi kukin numeroparit vuorotellen ja lisäsi ne sitten. Suorittimelle tämä näyttäisi suunnilleen tältä:
; Hypothetical RISC machine
; add 10 numbers in a to 10 numbers in b, storing results in c
; assume a, b, and c are memory locations in their respective registers
move $10, count ; count := 10
loop:
load r1, a
load r2, b
add r3, r1, r2 ; r3 := r1 + r2
store r3, c
add a, a, $4 ; move on
add b, b, $4
add c, c, $4
dec count ; decrement
jnez count, loop ; loop back if count is not yet 0
ret
Mutta vektoriprosessorille tämä tehtävä näyttää huomattavasti erilaiselta:
; assume we have vector registers v1-v3
; with size equal or larger than 10
move $10, count ; count = 10
vload v1, a, count
vload v2, b, count
vadd v3, v1, v2
vstore v3, c, count
ret
Huomaa täydellinen puuttuminen kiehkura ohjeissa, koska se on laitteisto , joka on suorittanut 10 sarjaoperaatiot: tehokkaasti silmukoiden määrää on selkeä per-opetusta perusteella.
Cray-tyylinen vektori-ISA ottaa tämän askeleen pidemmälle ja tarjoaa maailmanlaajuisen "laskurirekisterin", nimeltään Vector Length (VL):
; again assume we have vector registers v1-v3
; with size larger than or equal to 10
setvli $10 # Set vector length VL=10
vload v1, a # 10 loads from a
vload v2, b # 10 loads from b
vadd v3, v1, v2 # 10 adds
vstore v3, c # 10 stores into c
ret
Tähän lähestymistapaan liittyy useita säästöjä.
- tarvitaan vain kolme osoitteen käännöstä. Arkkitehtuurista riippuen tämä voi olla merkittävä säästö itsessään.
- Toinen säästö on itse käskyn nouto ja dekoodaus, joka on tehtävä vain kerran kymmenen sijasta.
- Koodi itsessään on myös pienempi, mikä voi johtaa tehokkaampaan muistin käyttöön, L1 -käskyvälimuistin koon pienenemiseen ja virrankulutuksen pienenemiseen.
- Ohjelman koon pienentyessä haaran ennustaminen on helpompaa.
- Koska pituus (vastaa SIMD-leveyttä) ei ole koodattu käskyyn, koodaus on paitsi pienempi, myös "tulevaisuudenkestävä" ja mahdollistaa jopa sulautettujen prosessorien suunnittelun harkita vektorien käyttöä pelkästään kaikkien muiden etujen saamiseksi , sen sijaan, että etsit korkeaa suorituskykyä.
Lisäksi nykyaikaisemmissa vektoriprosessorin ISA -standardeissa on otettu käyttöön "Fail on First" tai "Fault First" (katso alla), mikä tuo vielä enemmän etuja.
Mutta paljon enemmän, korkean suorituskyvyn vektoriprosessorissa voi olla useita toiminnallisia yksiköitä, jotka lisäävät nämä numerot rinnakkain. Näiden numeroiden välisten riippuvuuksien tarkistamista ei vaadita, koska vektorikäsky määrittää useita itsenäisiä toimintoja. Tämä yksinkertaistaa vaadittua ohjauslogiikkaa ja voi parantaa suorituskykyä edelleen välttämällä jumittumista. Matematiikkaoperaatiot saatiin siten kokonaisuudessaan paljon nopeammin päätökseen, mikä rajoitti tietojen noutamiseen muistista tarvittavaa aikaa.
Kaikkia ongelmia ei voi hyökätä tällä ratkaisulla. Tämäntyyppisten ohjeiden sisällyttäminen lisää väistämättä ydinprosessoria. Tämä monimutkaisuus saa tyypillisesti muut ohjeet toimimaan hitaammin - toisin sanoen aina, kun se ei lisää useita numeroita peräkkäin. Monimutkaisemmat ohjeet lisäävät myös dekooderien monimutkaisuutta, mikä saattaa hidastaa tavallisten ohjeiden, kuten normaalin lisäyksen, dekoodausta. ( Tätä voidaan lieventää pitämällä koko ISA RISC -periaatteissa: RVV lisää vain noin 190 vektoriohjetta jopa edistyneiden ominaisuuksien kanssa. )
Vektoriprosessorit on perinteisesti suunniteltu toimimaan parhaiten vain silloin, kun on käsiteltävä suuria määriä dataa. Tästä syystä tällaisia suorittimia löytyi pääasiassa supertietokoneista , koska itse supertietokoneet löydettiin yleensä paikoista, kuten sääennustuskeskuksista ja fysiikkalaboratorioista, joissa valtavia tietoja "murskataan". Kuten edellä on osoitettu ja RISC-V RVV on osoittanut , Vector ISA: n tehokkuus tuo kuitenkin muita etuja, jotka ovat vakuuttavia jopa sulautetuissa käyttötapauksissa.
Vektorin ohjeet
Yllä olevassa vektorin pseudokoodiesimerkissä on suuri oletus, että vektoritietokone voi käsitellä enemmän kuin kymmenen numeroa yhdessä erässä. Jos vektorirekisterissä on suurempi määrä numeroita, on mahdotonta, että tietokoneella on niin suuri rekisteri. Tämän seurauksena vektoriprosessori joko saa kyvyn suorittaa silmukoita itse tai paljastaa ohjelmoijalle jonkinlaisen vektoriohjausrekisterin (Status), joka tunnetaan yleensä nimellä Vector Length.
Itse toistuvat ohjeet löytyvät varhaisista vektoritietokoneista, kuten STAR-100, jossa yllä oleva toimenpide kuvattaisiin yhdellä ohjeella (jonkin verran vadd c, a, b, $10). Ne löytyvät myös x86 -arkkitehtuurista REPetuliitteenä. Kuitenkin vain hyvin yksinkertaiset laskelmat voidaan tehdä tehokkaasti laitteistossa tällä tavalla ilman erittäin suurta kustannusten nousua. Koska kaikkien operandien on oltava muistissa STAR-100-arkkitehtuuria varten, pääsyn aiheuttamasta viiveestä tuli myös valtava.
Mielenkiintoista on kuitenkin, että Broadcom sisälsi tilaa kaikkiin Videocore IV ISA: n vektoritoimintoihinREP kentälle, mutta toisin kuin STAR-100, joka käyttää toistoaan muistia, Videocore IV -toistot ovat kaikissa toiminnoissa, myös aritmeettiset vektoritoiminnot. Toistopituus voi olla pieni kahden tehon alue tai peräisin yhdestä skalaarirekisteristä.
Cray-1 otettiin ajatus käyttää rekisteri on pitää vektori tiedot erissä. Erän pituudet (Vector Length, VL) voitaisiin asettaa dynaamisesti erityisellä ohjeella, ja merkitys verrattuna Videocore IV: hen (ja mikä tärkeintä, kuten alla osoitetaan, myös SIMD) on se, että toistopituuden ei tarvitse olla osa käskyn koodaus. Tällä tavalla voidaan tehdä paljon enemmän työtä jokaisessa erässä, ja käskykoodaus on paljon tyylikkäämpi ja pienempi, ja sen ainoa haittapuoli on, että tämän lisäeräkäsittelykapasiteetin hyödyntämiseksi muistin kuormitus ja tallennusnopeus olivat vastaavasti myös lisääntymään. Tämän väitetään joskus olevan Cray-tyylisten Vector-prosessorien haitta: todellisuus on, että se vain ylittää suorituskyvyn, kuten GPU: ssa , joissa on täsmälleen sama ongelma. Sano puhekielellä: haluat numeroiden murskaamisen, tarvitset kaistanleveyttä.
Nykyaikaiset SIMD -tietokoneet väittävät parantavansa varhaista Cray -ohjelmaa käyttämällä suoraan useita ALU -yksiköitä, mikä tarjoaa paremman rinnakkaisuuden kuin vain normaalin skalaariputken käyttäminen. Nykyaikaiset vektoriprosessorit (kuten SX-Aurora TSUBASA ) yhdistävät molemmat antamalla useita tietoja useille sisäisille liukuhihnalla oleville SIMD ALU -yksiköille, jolloin Vector-ohjelma valitsee dynaamisen numeron ajon aikana. Maskeja voidaan käyttää tietojen valikoivaan lataamiseen ja tallentamiseen muistipaikkoihin, ja samoilla maskeilla voidaan poistaa SIMD ALU: iden käsittelyelementti käytöstä valikoivasti. Jotkin SIMD - prosessorit ( AVX-512 , ARM SVE2 ) kykenevät tällaiseen valikoivaan elementtikohtaiseen ( "ennustettu" ) käsittelyyn, ja juuri nämä ansaitsevat jonkin verran "vektoriprosessorin" nimikkeistön tai ainakin ansaitsevat pystyy "vektorin käsittelyyn". SIMD-prosessorit ilman elementtien ennakointia ( MMX , SSE , AltiVec ) eivät ehdottomasti.
Nykyaikaiset grafiikkasuorittimet, joissa on monia pieniä laskentayksiköitä, joilla kullakin on oma itsenäinen SIMD ALU, käyttävät SIMT ( Single Instruction Multiple Threads ) -nimeä. SIMT -yksiköt toimivat jaetusta yhden lähetyksen synkronoidusta opetusyksiköstä. "Vektorirekisterit" ovat erittäin leveitä ja putkilinjat ovat yleensä pitkiä. SIMT: n "kierteitykseen" liittyy tapa, jolla tietoja käsitellään itsenäisesti jokaisessa laskentayksikössä.
Lisäksi grafiikkasuorittimet, kuten Broadcom Videocore IV ja muut ulkoiset vektoriprosessorit, kuten NEC SX-Aurora TSUBASA, voivat käyttää vähemmän vektoriyksiköitä kuin leveys antaa ymmärtää: laitteiden sijaan 64 yksikköä 64-numeroiselle rekisterille. tee putkilinjainen silmukka yli 16 yksikköä hybridilähestymistapaa varten. Broadcom Videocore IV pystyy myös tähän hybridi-lähestymistapaan: nimellisesti todeten, että sen SIMD QPU -moottori tukee ohjeissaan 16-pituisia FP-matriisitoimintoja, se itse asiassa tekee ne 4 kerrallaan (toisen) "säikeiden" muodossa.
Esimerkki vektori -ohjeesta
Tässä esimerkissä aloitamme algoritmilla ("IAXPY"), näytä se ensin skalaarikäskyissä, sitten SIMD, sitten Predicated SIMD ja lopuksi Vector -ohjeet. Tämä auttaa vähitellen havainnollistamaan eroa perinteisen vektoriprosessorin ja modernin SIMD -prosessorin välillä. Aloitamme "DAXPY" -funktion 32 -bittisellä kokonaislukumuunnoksella, c :
void iaxpy(size_t n, int a, const int x[], int y[]) {
for (size_t i = 0; i < n; i++)
y[i] = a * x[i] + y[i];
}
Jokaisessa iteroinnissa jokaisella y: n elementillä on x -elementti kerrottuna a: lla ja lisätty siihen. Ohjelma on ilmaistu skalaarisessa lineaarisessa muodossa luettavuuden vuoksi.
Scalar Assembler
Skalaariversiomme tästä lataa yhden kustakin x: stä ja y: stä, käsittelee yhden laskelman, tallentaa yhden tuloksen ja silmukan:
loop:
load32 r1, x ; load one 32bit data
load32 r2, y
mul32 r1, a, r1 ; r1 := r1 * a
add32 r3, r1, r2 ; r3 := r1 + r2
store32 r3, y
addl x, x, $4 ; x := x + 4
addl y, y, $4
subl n, n, $1 ; n := n - 1
jgz n, loop ; loop back if n > 0
out:
ret
STAR-kaltainen koodi on edelleen ytimekäs, mutta koska STAR-100: n vektorisointi perustui suunnittelun perusteella muistin käyttöoikeuksiin, tarvitsemme nyt ylimääräisen muistipaikan tietojen käsittelemiseksi. Kaksinkertainen viive tarvitaan myös muistin käyttöoikeuden lisävaatimuksen vuoksi.
; Assume tmp is pre-allocated
vmul tmp, a, x, n ; tmp[i] = a * x[i]
vadd y, y, tmp, n ; y[i] = y[i] + tmp[i]
ret
Puhdas (ei-ennakoitu, pakattu) SIMD
Moderni pakattu SIMD -arkkitehtuuri, joka tunnetaan monilla nimillä (lueteltu Flynnin taksonomiassa ), voi tehdä suurimman osan toiminnoista erissä. Koodi on enimmäkseen samanlainen kuin skalaariversio. Oletamme, että sekä x että y on kohdistettu oikein (aloita vain 16: n monikerta) ja että n on 4: n monikerta, koska muuten tarvitaan jotain asennuskoodia maskin laskemiseen tai skalaariversion suorittamiseen. Oletamme myös yksinkertaisuuden vuoksi, että SIMD -ohjeissa on mahdollisuus toistaa skalaarioperandit automaattisesti, kuten ARM NEON voi. Jos näin ei tapahdu, on käytettävä "splat" -lähetystä, joka kopioi skalaari -argumentin SIMD -rekisterin yli:
splatx4 v4, a ; v4 = a,a,a,a
Aikaa kuluu pohjimmiltaan sama kuin y = mx + cedellä kuvatun vektorin toteutus .
vloop:
load32x4 v1, x
load32x4 v2, y
mul32x4 v1, a, v1 ; v1 := v1 * a
add32x4 v3, v1, v2 ; v3 := v1 + v2
store32x4 v3, y
addl x, x, $16 ; x := x + 16
addl y, y, $16
subl n, n, $4 ; n := n - 4
jgz n, vloop ; go back if n > 0
out:
ret
Huomaa, että sekä x- että y-osoittimia lisätään 16: lla, koska niin kauan (tavuina) on neljä 32-bittistä kokonaislukua. Päätettiin, että algoritmi on vain selviytyä 4-leveä SIMD, siis vakio on kovakoodattu ohjelmaan.
Valitettavasti SIMD: lle vihje oli edellä oletuksessa ", että n on 4: n monikerta" sekä "kohdistettu pääsy", joka on selvästi rajoitettu erikoistarkoitus.
Todellisuudessa yleiskäyttöisissä silmukoissa, kuten kannettavissa kirjastoissa, joissa n: ää ei voi rajoittaa tällä tavalla, SIMD: n asennuksen ja puhdistuksen yleiskustannukset SIMD: n leveyden ei-moninkertaisiksi selviytymiseksi voivat ylittää paljon sisällä olevien ohjeiden määrän silmukka itse. Olettaen pahimmassa tapauksessa, että laitteisto ei voi käyttää väärin kohdistettuja SIMD-muistin käyttöjä, todellinen algoritmi:
- Ensin on oltava valmisteleva osio, joka käsittelee kohdistamattomia tietoja ensimmäiseen pisteeseen asti, jolloin SIMD-muistiin kohdistetut toiminnot voivat ottaa vallan. tämä sisältää joko (hitaampia) vain skalaaritoimintoja tai pienempiä pakattuja SIMD-toimintoja. jokainen kopio toteuttaa koko algoritmin sisäisen silmukan
- suorita kohdistettu SIMD -silmukka SIMD -enimmäisleveydellä muutamaan viimeiseen elementtiin asti (jäljellä olevat osat, jotka eivät sovi kiinteään SIMD -leveyteen)
- on puhdistusvaihe, joka on valmisteluvaiheen tavoin yhtä suuri ja monimutkainen.
Kahdeksan leveä SIMD vaatii sisäisen silmukan algoritmin toistamista ensin neljällä leveällä SIMD-elementillä, sitten kahden leveän SIMD: llä, sitten yhdellä (skalaari), testin ja haaran jokaisen välissä kattaakseen ensimmäisen ja viimeisen jäljellä olevan SIMD: n elementtejä (0 <= n <= 7).
Tämä yli kolminkertaistaa koko koodin, itse ääritapauksissa se johtaa suuruusluokkaa kasvu opetusta count! Tämä voidaan helposti osoittaa kokoamalla iaxpy esimerkki AVX-512 , käyttäen vaihtoehtoja "-O3 -march=knl"ja GCC .
Ajan myötä, kun ISA kehittyy jatkuvasti parantamaan suorituskykyä, se johtaa siihen, että ISA Architects on lisännyt 2 leveän SIMD: n, sitten 4 leveän SIMD: n, sitten 8 leveän ja ylöspäin. Aloimme siis nähdä, miksi AVX-512 on olemassa x86: ssa.
Ilman ennakointia, mitä laajempi SIMD -leveys, sitä pahemmat ongelmat pahenevat, mikä johtaa massiiviseen opcode -leviämiseen, suorituskyvyn heikkenemiseen, lisävirrankulutukseen ja tarpeettomaan ohjelmiston monimutkaisuuteen.
Vektoriprosessorit sitä vastoin on suunniteltu antamaan vaihtelevan pituisia laskelmia mielivaltaiselle lukulle, n, ja vaativat siten hyvin vähän asennusta ja puhdistusta. Verrattuna niihin SIMD ISA -laitteisiin, joissa on naamarit (mutta ei setvlohjeita), vektoriprosessorit tuottavat paljon pienempää koodia, koska niiden ei tarvitse suorittaa nimenomaisia maskilaskelmia kattaakseen viimeiset elementit (kuvattu alla).
Ennakoitu SIMD
Jos oletetaan hypoteettinen ennustettu (peitekykyinen) SIMD ISA, ja jälleen olettaen, että SIMD -ohjeet voivat selviytyä väärin kohdistetuista tiedoista, käskysilmukka näyttäisi tältä:
vloop:
# prepare mask. few ISAs have min though
min t0, n, $4 ; t0 = min(n, 4)
shift m, $1, t0 ; m = 1<<t0
sub m, m, $1 ; m = (1<<t0)-1
# now do the operation, masked by m bits
load32x4 v1, x, m
load32x4 v2, y, m
mul32x4 v1, a, v1, m ; v1 := v1 * a
add32x4 v3, v1, v2, m ; v3 := v1 + v2
store32x4 v3, y, m
# update x, y and n for next loop
addl x, t0*4 ; x := x + t0*4
addl y, t0*4
subl n, n, t0 ; n := n - t0
# loop?
jgz n, vloop ; go back if n > 0
out:
ret
Tässä voimme nähdä, että koodi on paljon puhtaampi, mutta hieman monimutkainen: ainakin ei ole asetuksia tai puhdistusta: silmukan viimeisellä iteraatiolla predikaattimaski asetetaan joko 0b0000, 0b0001, 0b0011, 0b0111 tai 0b1111 , jolloin suoritetaan 0–4 SIMD -elementtitoimintaa. Yksi mahdollinen lisäkomplikaatio: joillakin RISC ISA -laitteilla ei ole "min" -käskyä, vaan niiden on käytettävä haara- tai skalaaripredikaattia.
On selvää, kuinka ennalta määrätty SIMD ansaitsee ainakin termin "vektorikykyinen", koska se pystyy selviytymään vaihtelevan pituisista vektoreista käyttämällä predikaattimaskeja. Viimeinen kehitysvaihe "todellisen" vektori -ISA: n suhteen on kuitenkin se, ettei ISA: ssa ole todisteita lainkaan SIMD -leveydestä, jättäen sen kokonaan laitteiston tehtäväksi.
Puhdas (totta) vektori ISA
Cray-tyylisissä Vector ISA -laitteissa, kuten RVV, käytetään käskyä "setvl" (set Vector Length). Laitteisto määrittää ensin kuinka monta data -arvoa se voi käsitellä yhdessä "vektorissa": tämä voi olla joko todellisia rekistereitä tai sisäinen silmukka (edellä mainittu hybridimenetelmä). Tätä enimmäismäärää (laitteistojen "kaistoja") kutsutaan nimellä "MVL" (suurin vektoripituus). Huomaa, että kuten näimme SX-Aurorassa ja Videocore IV: ssä, MVL voi olla todellinen laitteistokaistan määrä tai virtuaalinen . (Huom: Kuten ARM SVE2 opetusohjelma, ohjelmoijat saa tehdä sitä virhettä olettaen kiinteän Vector leveys: siis MVL ei paljon, että ohjelmoija tarvitsee tietää. Tämä voi olla hieman hämmentävää vuosien jälkeen SIMD mielentila).
Kun soitat setvl: lle käsiteltävien jäljellä olevien tietoelementtien määrällä, "setvl" on sallittu (enemmän kuin pakollinen) rajoittaa sen enimmäisvektoripituuteen (MVL) ja palauttaa siten todellisen numeron, jonka laitteisto voi käsitellä seuraavat vektoriohjeet ja asettaa sisäisen erityisrekisterin "VL" samaan määrään. ARM viittaa tähän tekniikkaan "Vector Length Agnostic" -ohjelmoinniksi SVE2: n opetusohjelmissaan.
Alla on Cray-tyylinen Vector Assembler samalle SIMD-tyylille. Katso tarkasti, miten t0: ta (joka sisältää kätevän kopion VL: stä voi vaihdella) käytetään kovakoodattujen vakioiden sijaan:
vloop:
setvl t0, n # VL=t0=min(MVL, n)
vld32 v0, x # load vector x
vld32 v1, y # load vector y
vmadd32 v1, v0, a # v1 += v0 * a
vst32 v1, y # store Y
add y, t0*4 # advance y by VL*4
add x, t0*4 # advance x by VL*4
sub n, t0 # n -= VL (t0)
bnez n, vloop # repeat if n != 0
Tämä ei todellakaan eroa SIMD -versiosta (käsittelee 4 tietoelementtiä silmukkaa kohti) tai alkuperäisestä Scalar -versiosta (käsittelee vain yhtä). Voimme nähdä, että n sisältää edelleen tietojen määrä elementtejä jäljellä voidaan käsitellä, mutta t0 sisältää kopion VL - numero, joka on menossa voidaan käsitellä jokaisen iteraation. t0 vähennetään n: stä jokaisen iteraation jälkeen, ja jos n on nolla, kaikki elementit on käsitelty.
Useita kiehtovia asioita on huomioitava, kun verrataan ennakoitua SIMD -kokoonpanovaihtoehtoa:
setvlohje on upotettu sitäminopetusta- Jossa SIMD variantti koodattu sekä leveys (4) luomiseen maskin ja että SIMD leveys (load32x4 jne.) Vector ISA ekvivalenttia ei ole tällaista rajoitusta. Tämä tekee Vector-ohjelmista sekä kannettavia, toimittajasta riippumattomia että tulevaisuuden kestäviä.
- asetus VL luo tehokkaasti piilotetun predikaattimaskin , jota sovelletaan automaattisesti vektoreihin
- Jos ennustetulla SIMD: llä maskin bittipituus on rajoitettu siihen, joka voidaan pitää skalaari- (tai erikoismaski) -rekisterissä, Vector ISA: n maskirekisterissä ei ole tällaista rajoitusta. Cray-I-vektorit voivat olla hieman yli 1000 elementtiä (vuonna 1977).
Näin voimme nähdä hyvin selvästi, kuinka Vector ISA: t vähentävät ohjeiden määrää.
Huomaa myös, että aivan kuten Predicated SIMD -muunnelma, osoittimet x: ään ja y: hen edistyvät t0 kertaa neljä, koska molemmat osoittavat 32 -bittiseen dataan, mutta n pienenee suoralla t0: lla. Kiinteäkokoiseen SIMD-kokoonpanijaan verrattuna on hyvin vähän ilmeistä eroa: x ja y edistyvät kovakoodatulla vakiona 16, n pienenee kovakoodatulla 4, joten aluksi on vaikea ymmärtää merkitystä. Ero tulee siitä, että Vector -laitteisto pystyy suorittamaan neljä samanaikaista toimintoa, tai 64 tai 10 000, se olisi täsmälleen sama Vector Assembler kaikille, eikä SIMD -puhdistuskoodia vieläkään olisi . Jopa Predicate-yhteensopivaan SIMD: hen verrattuna se on silti pienempi, selkeämpi, tyylikkäämpi ja käyttää vähemmän resursseja.
Meillä ei ole vain paljon pienempää ohjelmaa (säästää L1 -välimuistin kokoa), mutta kuten aiemmin mainittiin, Vector -versio voi antaa paljon enemmän tietojenkäsittelyä ALU -laitteille, mikä taas säästää virtaa, koska Instruction Decode ja Issue voivat olla käyttämättömiä.
Vielä yksi kiehtova seikka: funktioon tulevien elementtien määrä voi alkaa nollasta . Tämä asettaa Vector pituus nollaksi, mikä käytännössä poistaa käytöstä kaikki Vector ohjeita, kääntämällä ne ei-ops , suorituksen. Näin ollen, toisin kuin ei-ennalta määritetty SIMD, vaikka ei ole käsiteltäviä elementtejä, ei silti ole hukkaan mennyttä puhdistuskoodia.
Esimerkki vektorin pienentämisestä
Tässä esimerkissä aloitamme algoritmilla, johon liittyy pelkistys. Aivan kuten edellisessä esimerkissä, näytämme sen ensin skalaarikäskyissä, sitten SIMD: ssä ja lopuksi vektoriohjeissa. Aloitamme c : stä:
void (size_t n, int a, const int x[]) {
int y = 0;
for (size_t i = 0; i < n; i++)
y += x[i];
return y;
}
Tässä käytetään akkua (y) kaikkien matriisin x arvojen laskemiseksi yhteen.
Scalar Assembler
Skalaariversiomme tästä lataa jokaisen x: stä, lisää sen y: hen ja silmukan:
set y, 0 ; y initialised to zero
loop:
load32 r1, x ; load one 32bit data
add32 y, y, r1 ; y := y + r1
addl x, x, $4 ; x := x + 4
subl n, n, $1 ; n := n - 1
jgz n, loop ; loop back if n > 0
out:
ret y ; returns result, y
Tämä on hyvin suoraviivaista. "y" alkaa nollasta, 32 -bittisiä kokonaislukuja ladataan yksi kerrallaan r1: een, lisätään y: hen ja taulukon "x" osoite siirretään taulukon seuraavaan elementtiin.
SIMD -vähennys
Tästä ongelmat alkavat. SIMD suunnittelun siihen pysty laskutoimituksia "inter-elementti". Yhden SIMD -rekisterin elementti 0 voidaan lisätä toisen rekisterin elementtiin 0, mutta osaa 0 ei saa lisätä mihinkään muuhun kuin toiseen elementtiin 0. Tämä asettaa joitakin vakavia rajoituksia mahdollisille toteutuksille. Oletetaan yksinkertaisuuden vuoksi, että n on täsmälleen 8:
addl r3, x, $16 ; for 2nd 4 of x
load32x4 v1, x ; first 4 of x
load32x4 v2, r3 ; 2nd 4 of x
add32x4 v1, v2, v1 ; add 2 groups
Tässä vaiheessa olemme tehneet neljä lisäystä:
-
x[0]+x[4]- Ensimmäinen SIMD ADD: ensimmäisen ryhmän elementti 0 lisättiin toisen ryhmän elementtiin 0 -
x[1]+x[5]- Toinen SIMD ADD: ensimmäisen ryhmän elementti 1 lisättiin toisen ryhmän elementtiin 1 -
x[2]+x[6]- Kolmas SIMD ADD: ensimmäisen ryhmän elementti 2 lisättiin toisen ryhmän elementtiin 2 -
x[3]+x[7]- Neljäs SIMD ADD: ensimmäisen ryhmän elementti 3 lisättiin toisen ryhmän elementtiin 2
mutta 4-leveä SIMD hetkellä pysty suunnittelun lisäämällä x[0]+x[1]esimerkiksi asiat menevät nopeasti alas aivan kuten se teki yleisessä tapauksessa, jossa käytetään SIMD yleiskäyttöön IAXPY silmukoita. Yhteenvetona meidän neljän osittaisia tuloksia, kaksi laajuinen SIMD voidaan käyttää, sen jälkeen yksi yksittäinen Scalar lisäosa, lopulta tuottaa vastauksen, mutta usein tiedot on siirrettävä pois omistettu SIMD rekistereistä ennen viimeistä skalaarin laskenta voidaan suorittaa .
Jopa yleisellä silmukalla (n ei ole kiinteä), ainoa tapa käyttää 4-leveää SIMD: tä on olettaa neljä erillistä "virtaa", joista jokainen on neljän elementin kompensoima. Lopuksi neljä ositulosta on laskettava yhteen. Muita tekniikoita ovat sekoitus: verkossa on esimerkkejä AVX-512 : sta vaakasumman tekemisestä.
Ohjelman koon ja monimutkaisuuden lisäksi liukulukulaskenta aiheuttaa mahdollisen lisäongelman: se, että arvoja ei lasketa yhteen tiukassa järjestyksessä (neljä osittaista tulosta), voi johtaa pyöristysvirheisiin.
Vector ISA -vähennys
Vector-käskysarjoissa on aritmeettisia pienennysoperaatioita sisäänrakennettu ISA: han. Jos voimme olettaa, että n on pienempi tai yhtä suuri kuin vektorin enimmäispituus, tarvitaan vain kolme käskyä:
setvl t0, n # VL=t0=min(MVL, n)
vld32 v0, x # load vector x
vredadd32 y, v0 # reduce-add into y
Koodi, kun n on suurempi kuin vektorin enimmäispituus, ei ole paljon monimutkaisempi, ja se on samanlainen kuvio kuin ensimmäinen esimerkki ("IAXPY").
set y, 0
vloop:
setvl t0, n # VL=t0=min(MVL, n)
vld32 v0, x # load vector x
vredadd32 y, y, v0 # add all x into y
add x, t0*4 # advance x by VL*4
sub n, t0 # n -= VL (t0)
bnez n, vloop # repeat if n != 0
ret y
Algoritmin yksinkertaisuus on karkea verrattuna SIMD: hen. Jälleen, aivan kuten IAXPY-esimerkissä, algoritmi on pituusagnostinen (jopa sulautetuissa toteutuksissa, joissa vektorin enimmäispituus voi olla vain yksi).
Laitteistototeutukset voivat, jos ne ovat varmoja, että oikea vastaus saadaan, suorittaa vähennyksen rinnakkain. Jotkut Vector ISA: t tarjoavat rinnakkaisen pienennystilan nimenomaisena vaihtoehtona, kun ohjelmoija tietää, että mahdollisilla pyöristysvirheillä ei ole väliä, ja pieni viive on kriittinen.
Tämä esimerkki korostaa jälleen keskeistä keskeistä perustavaa laatua olevaa eroa "todellisten" vektoriprosessorien ja SIMD -prosessorien välillä, mukaan lukien useimmat kaupalliset grafiikkasuorittimet, jotka ovat "innoittamia" vektoriprosessorien ominaisuuksista.
Oivalluksia esimerkeistä
Verrattuna mihin tahansa SIM -prosessoriin, joka väittää olevansa vektoriprosessori, ohjelman koon pienentäminen suuruusluokassa on melkein järkyttävää. Tällä eleganssitasolla ISA -tasolla on kuitenkin melko korkea hintalaitteisto laitteistotasolla:
- IAXPY -esimerkistä näemme, että toisin kuin SIMD -prosessorit, jotka voivat yksinkertaistaa sisäistä laitteistoaan välttämällä väärin kohdistetun muistin käytön, vektoriprosessori ei voi päästä eroon tällaisesta yksinkertaistamisesta: kirjoitetaan algoritmeja, jotka luontaisesti luottavat Vector Load and Storen onnistumiseen, riippumatta vektorin alkukohdistuksesta.
- Vaikka pelkistysesimerkistä nähdään, että permute-ohjeita lukuun ottamatta SIMD välttää täysin kaistojen välisiä toimintoja (elementti 0 voidaan lisätä vain toiseen elementtiin 0), vektoriprosessorit käsittelevät tätä head-on. Mitä ohjelmoijat joutuvat tekemään ohjelmistossa (sekoituksen ja muiden temppujen avulla tietojen vaihtamiseksi oikealle "kaistalle") Vektoriprosessorien on tehtävä laitteistossa automaattisesti.
Kaiken kaikkiaan sitten on vaihtoehto kummasta tahansa
- monimutkainen ohjelmisto ja yksinkertaistettu laitteisto (SIMD)
- yksinkertaistettu ohjelmisto ja monimutkainen laitteisto (vektoriprosessorit)
Nämä jyrkät erot erottavat vektoriprosessorin SIMD -prosessorista.
Vektoriprosessorin ominaisuudet
Kun monet SIMD -ISAt "lainaavat" tai "inspiroivat" alla olevasta luettelosta, tyypillisiä ominaisuuksia, jotka ovat hyvällä vektoriprosessorilla, ovat:
- Vector Load and Store - nämä säästävät luonnostaan virtuaalimuistin hauissa ja on suunniteltu syöttämään tiedot rekistereihin mahdollisimman vaivattomasti. Kehittyneet vektorikuormitus-/tallennusparannukset sisältävät tuen rakenteiden pakkaamiseen , epäonnistumiseen, keräämiseen, hajottamiseen , indeksointiin, yksikkö- ja elementtivaiheisiin.
- Naamioidut toiminnot - kuten nykyään yleisesti GPU: ssa , predikaattimaskit sallivat rinnakkaiset, jos/sitten/muut -rakenteet ilman haaroja (jotka ovat luonteeltaan skaalareita)
- Pakkaa ja laajenna- tavallisesti bittimaskin avulla tiedot pakataan tai laajennetaan (jaetaan uudelleen) lineaarisesti sen perusteella, onko maskin bitit asetettu vai selkeitä, säilyttäen kuitenkin aina järjestyksen ja koskaan päällekkäisiä arvoja (toisin kuin Gather-Scatter eli permute) . Nämä ohjeet ovat AVX-512-laitteessa
- Register Gather, Scatter (alias permute) - vähemmän rajoittava yleisempi muunnelma Pakkaa/laajenna -teemasta, joka sen sijaan vaatii yhden vektorin määrittämään indeksit, joita käytetään toisen vektorin "uudelleenjärjestämiseen". Kerää/hajota on monimutkaisempi toteuttaa kuin Pakkaa/Laajenna, ja koska se ei ole peräkkäin, se voi häiritä vektoriketjutusta . Ei pidä sekoittaa Gather-hajonta Memory Load / Store tilat, Kerää / Scatter Vector toimintansa vaikuttavat Vector rekistereitä , ja usein kutsutaan permute ohjeen sijasta.
- Splat ja Extract - hyödyllisiä Scalar- ja Vector -vuorovaikutuksessa, ne lähettävät yhden arvon vektorin poikki tai poimivat yhden kohteen vektorista.
- Iota- hyvin yksinkertainen ja strategisesti hyödyllinen ohje, joka pudottaa peräkkäin kasvavat välituotteet peräkkäisiksi elementeiksi. Yleensä alkaa nollasta.
-
Pienennys ja iterointi - toiminnot, jotka suorittavat kartoitusta vektorille (esimerkiksi etsi koko vektorin suurin arvo tai summaa kaikki elementit). Iteraatio on siinä muodossa,
x[i] = y[i] + x[i-1]missä pelkistys on muotoax = y[0] + y[1]… + y[n-1] - Matriisikertoimen tuki- joko lataamalla tietoja algoritmisesti muistista tai järjestämällä uudelleen (uudelleenmäärittelemällä) normaalisti lineaarinen pääsy vektorielementteihin tai tarjoamalla "akkuja", mielivaltaisen kokoisia matriiseja voidaan käsitellä tehokkaasti. IBM POWER10 tarjoaa MMA -ohjeita, vaikka satunnaisia matriisileveyksiä varten, jotka eivät sovi täsmälleen SIMD -koon tietojen toistotekniikoihin, tarvitaan rekisteritiedoston resursseja. Aspex ASP Linedancerissa oli 2D/3D -muistin uudelleenjärjestävä DMA -moottori, joka vaati huomattavia ponnisteluja optimaaliseen käyttöön. NVidia tarjoaa korkean tason Matrix CUDA -sovellusliittymän, vaikka sisäisiä tietoja ei ole saatavilla. Resurssitehokkain tekniikka on muutoin lineaaristen vektoritietojen käyttöoikeuden järjestäminen paikan päällä.
- Kehittyneet matematiikkamuodot- sisältää usein Galois-kenttäaritmetiikan , mutta voi sisältää binäärikoodatun desimaalin tai desimaalin kiinteän pisteen ja tuen paljon suuremmille (mielivaltaisen tarkkuuden) aritmeettisille operaatioille tukemalla rinnakkaista siirtoa ja suorittamista
- Bittien käsittely- mukaan lukien vektoriset versiot bittitason permutaatiotoiminnoista, bittikentän lisäys ja poiminta, sentrifugitoiminnot, väestömäärä ja monet muut .
GPU -vektorien käsittelyominaisuudet
Monet 3D Shader -sovellukset tarvitsevat trigonometrisiä toimintoja sekä lyhyet vektorit tavallisiin toimintoihin (RGB, ARGB, XYZ, XYZW), jotka ovat tyypillisesti nykyaikaisissa grafiikkasuorittimissa vektoriprosessoreiden lisäksi:
- Osavektoreiksi - elementit voivat tyypillisesti sisältää kaksi, kolme tai neljä osaelementtejä (vec2, vec3, vec4) missä tahansa hieman predikaatti maskin koskee koko vec2 / 3/4, ei elementit on osa-vektori. Alivektoreita esitetään myös RISC-V RVV: ssä (nimeltään "LMUL"). Subvektorit ovat tärkeä osa Vulkan SPIR-V -laatua.
- Alivektori Swizzle- alias "Lane Shuffling", joka mahdollistaa vektoreiden välisen laskennan ilman ylimääräisiä (kalliita, tuhlaavia) ohjeita siirtää alielementit oikeille SIMD "kaistoille". Säästää myös predikaattimaskin bittejä. Käytännössä tämä on alivektorin lennon aikana oleva mini-permute , joka on voimakkaasti mukana 3D Shader -binaaritiedostoissa, ja se on riittävän tärkeä ollakseen osa Vulkan SPIR-V -spesifikaatiota. Broadcom Videocore IV käyttää terminologiaa "Lane rotate", kun muu toimiala käyttää termiä "swizzle" .
- Transsendenttiset - trigonometriset operaatiot, kuten sini , kosini ja logaritmi, ovat ilmeisesti paljon pääasiassa 3D -muodossa kuin monissa vaativissa HPC -työkuormissa. Kiinnostavaa on kuitenkin se, että nopeus on paljon tärkeämpää kuin 3D: n tarkkuus GPU: ille, jossa pikselikoordinaattien laskeminen ei yksinkertaisesti vaadi suurta tarkkuutta. Vulkan erittely tunnistaa tämän ja laskee yllättävän alhainen tarkkuusvaatimukset, jotta GPU Laitteisto voi vähentää virrankulutusta. MIPS-3D- laajennuksessa tutkitaan käsitettä tarkkuuden vähentämisestä siellä, missä sitä ei yksinkertaisesti tarvita .
Lisäominaisuuksiin kuuluu tekstuurikartoitusyksikkö, joka on joskus erillinen yksikkö GPU -pääprosessorista. Mukana ovat usein myös tekstuurin interpolointiohjeet ja useita muita erikoisohjeita, kuten vektorin normalisointi sekä pisteellinen tuote .
Nykyaikaisista GPU -ohjesarjoista ei ole paljon julkisesti saatavilla. Lisätietoja ja vihjeitä GPU Vector ISA -ominaisuuksista löytyy tutkimalla SPIR-V- määritystä, Vulkan-määritystä ja OpenCL- määritystä. Nämä sovellusliittymät ovat Khronos -ryhmän luomia jäseniä, kuten Intel, Google, AMD ja NVIDIA, ja tarjoavat siten tietoa maailman nopeimpien grafiikkasuorittimien ominaisuuksista. Myös apua on MALI Midgard GPU: n käänteisesti suunniteltu ohjesarja.
Vika (tai epäonnistuminen) ensin
ARM SVE2: ssa ja RISC-V: ssä käyttöön otettu RVV on spekulatiivisen peräkkäisen vektorikuormituksen käsite. ARM SVE2: lla on erityinen rekisteri nimeltä "First Fault Register", jossa RVV muuttaa (katkaisee) vektoripituuden (VL).
Ensimmäisen perusperiaate on yrittää suurta peräkkäistä vektorikuormitusta, mutta antaa laitteiston sallia mielivaltaisesti katkaista ladatun todellisen määrän joko määrään, joka onnistuisi nostamatta muistivirhettä, tai yksinkertaisesti määrään (suurempi kuin nolla), joka on kätevin. Tärkeä tekijä on, että myöhemmät ohjeet ilmoitetaan tai ne voivat määrittää tarkasti, kuinka monta latausta todella onnistui, käyttämällä tätä määrää vain työn suorittamiseen todellisuudessa ladatuille tiedoille.
Vertaa tätä tilannetta SIMD: hen, joka on kiinteä (joustamaton) kuormitusleveys ja kiinteä tietojenkäsittelyleveys, joka ei pysty käsittelemään sivun rajoja ylittäviä kuormia, ja vaikka ne olisivatkin, he eivät pysty sopeutumaan siihen, mikä todella onnistui, mutta paradoksaalisesti, Jos SIMD -ohjelma edes yrittäisi selvittää etukäteen (jokaisessa sisäpiirissä, joka kerta), mikä voisi optimaalisesti onnistua, nämä ohjeet vain estävät suorituskykyä, koska ne olisivat välttämättä osa kriittistä sisäpiiriä.
Tämä alkaa viitata siihen, miksi ffirst on niin innovatiivinen, ja sitä kuvaa parhaiten memcpy tai strcpy, kun se toteutetaan tavallisella 128-bittisellä ei-ennakoidulla ei-ensimmäisellä SIMD: llä. IBM POWER9: llä käsin optimoitujen ohjeiden määrä strncpy: n toteuttamiseen on yli 240. Sitä vastoin sama strncpy-rutiini käsin optimoidussa RVV-kokoonpanossa on vain 22 käskyä.
Yllä oleva SIMD -esimerkki voi mahdollisesti vikata ja epäonnistua muistin lopussa, koska yritykset lukea liian monta arvoa: se voi myös aiheuttaa huomattavan määrän sivuja tai virheellisiä vikoja samalla tavalla ylittämällä rajat. Sitä vastoin antamalla vektoriarkkitehtuurille vapauden päättää, kuinka monta elementtiä ladataan, strncpy: n ensimmäinen osa, jos se alun perin alittaa optimaalisen huonon muistin rajan, voi palauttaa juuri sen verran kuormia, että silmukan myöhemmissä iteroinneissa Vectorized -muistilukujen erät on optimoitu optimaalisesti taustalla olevien välimuistien ja virtuaalimuistijärjestelyjen kanssa. Lisäksi laitteisto voi halutessaan käyttää tilaisuutta lopettaa minkä tahansa silmukan iteroinnin muistin lukeminen täsmälleen sivurajalla (välttäen kallista toista TLB -hakua) ja spekulatiivinen suoritus valmistelee seuraavan virtuaalimuistisivun, kun tietoja käsitellään edelleen silmukka. Kaikki tämä määräytyy laitteiston , ei itse ohjelman perusteella.
Suorituskykyä ja nopeutta
Olkoon r vektorin nopeussuhde ja f vektorisaatiosuhde. Jos vektoriyksikölle kuluva aika lisätä 64 numeron matriisi on 10 kertaa nopeampi kuin vastaava skalaariluku, r = 10. Lisäksi jos ohjelman toimintojen kokonaismäärä on 100, joista vain 10 on skalaaria (vektorisoinnin jälkeen), sitten f = 0,9, eli vektoriyksikkö tekee 90% työstä. Se seuraa saavutettavaa nopeutta:
Joten vaikka vektoriyksikön suorituskyky on erittäin korkea ( ), saamme nopeuden pienemmän kuin , mikä viittaa siihen, että suhde f on ratkaiseva suorituskyvylle. Tämä suhde riippuu kokoamisen tehokkuudesta, kuten muistin elementtien vierekkäisyys.
Heterogeenisten tietojenkäsittelyarkkitehtuurien ohjelmointi
Eri koneet on suunniteltu sisältämään sekä perinteiset prosessorit että vektoriprosessorit, kuten Fujitsu AP1000 ja AP3000. Tällaisten heterogeenisten koneiden ohjelmointi voi olla vaikeaa, koska eri prosessorien ominaisuuksia parhaiten hyödyntävien ohjelmien kehittäminen lisää ohjelmoijan taakkaa. Se lisää koodin monimutkaisuutta ja vähentää koodin siirrettävyyttä vaatimalla laitteistokohtaisen koodin limittämistä koko sovelluskoodin läpi. Sovelluskuorman tasapainottaminen prosessorien välillä voi olla ongelmallista, etenkin kun otetaan huomioon, että niillä on tyypillisesti erilaiset suorituskykyominaisuudet. Ongelman ratkaisemiseksi on olemassa erilaisia käsitteellisiä malleja, esimerkiksi käyttämällä koordinointikieltä ja ohjelmien rakennuspalikoita (ohjelmointikirjastot tai korkeamman tason toiminnot). Jokaisella lohkolla voi olla eri natiivitoteutus kullekin prosessorityypille. Käyttäjät yksinkertaisesti ohjelmoivat näiden abstraktioiden avulla ja älykäs kääntäjä valitsee parhaan toteutuksen kontekstin perusteella.
Katso myös
- SX -arkkitehtuuri
- Duncanin taksonomia putkilinjaisiin vektoriprosessoreihin
- GPGPU
- Laske ydin
- Virran käsittely
- SIMD
- Automaattinen vektorisointi
- Ketjutus (vektorin käsittely)
- Tietokone toimintoja varten
- RISC-V , avoin ISA-standardi, johon liittyy muuttuvan leveyden vektorilaajennus .
- Piipun prosessori
- Tensorin prosessointiyksikkö
- Supertietokoneen historia
- Supertietokoneen arkkitehtuuri
Ulkoiset linkit
- Rinnakkaislaskennan kehityksen historia (1955-1993)
- Vector Computing, Past Present and Future, kirjoittanut Steve Scott, Cray Inc.
- NEC SX-Aurora ISA -opas
- Broadcom VideoCore IV -resurssit
- RISC-V Vectors, CS152, kevät 2020
- Cray-i-laitteiston käyttöoppaan luvut 1-3
- 1977 Cray-I -laitteiston käyttöopas
- Carnegie -yliopiston kurssi GPU: sta ja vektori -ISA: sta