Rinnakkaistietokoneet luento 6 521475S
Silmukkamuunnokset Silmukkamuunnoksilla silmukat muunnetaan joihinkin edellä esitettyihin rinnakkaismuotoihin Jakson kutistaminen (cycle shrinking) tämä muunnos soveltuu tapauksiin joissa riippuvuussykli liittyy iteraatioihin jotka ovat kaukana toisistaan Muuttaa sarjamuotoisen DO-silmukan kahdeksi sisäkkäiseksi silmukaksi: ulompi silmukka on sarjamuotoinen ja sisempi rinnakkaismuodossa Jakson kutistaminen erottaa lauseiden riippumattomat osat ja muodostaa rinnakkaisen sisäsilmukan
Esim: do i=1,n, step 1 a(i+k) = b(i) 1 b(i+k) = a(i) + c(i) Silmukalla on vakio riippuvuussykli jossa jokainen riippuvuusvektori on muotoa d = k (luotua muuttujaa käytetään k iteraation päästä: a ja b muuttujat) Jos riippuvuuden etäisyys on suurempi kuin 1, eli k > 1, voidaan silmukka muuttaa nopeampaan muotoon: do i1=1,n, step k doall i=i1, i1 + k 1 a(i+k) = b(i) 1 b(i+k) = a(i) + c(i) all... i1 i1+1 i1+2... k = 3
Jos silmukassa on useita vakioriippuvuuksia, silmukan läpikäyntiaikaa voidaan pienentää riippuvuuksien minimietäisyyteen verrannollisella tekijällä Esim: do i = 1,n x(i) = y(i) + z(i) y(i+3) = x(i-4)*w(i) Silmukalla on kaksi riippuvuutta: toinen pituudeltaan 3 (y:n kautta) ja toinen 4 (x:n kautta) Tämä tarkoittaa, että silmukka voidaan suorittaa kolmen (= min(3, 4)) iteraation samanaikaisissa lohkoissa: do j = 1,n, step 3 doall i = j, j+2 x(i) = y(i) + z(i) y(i+3) = x(i-4)*w(i) all
Katsotaan seuraavaksi silmukkaa jonka iteraatioavaruus on moniulotteinen Esim: do i = 3, n do j = 5, m a(i,j) = b(i-3,j-5) b(i,j) = a(i-2,j-4) Riippuvuusmatriisi on: D 2 = 4 3 5 d1 d2 i j
Jakson kutistamista voidaan soveltaa molempiin indekseihin erikseen, eli riippuvuusmatriisin riveihin Ulompi silmukka voidaan kutistaa tekijän 2 = min(2,3) verran ja sisempi silmukka tekijän 4 = min(4,5) verran, eli: do i1 = 3,N, step 2 do j1 = 5,m, step 4 doall i = i1, i1 + 1 doall j = j1, j1 + 3 a(i,j) = b(i-3,j-5) i b(i,j) = a(i-2,j-4) all all j Uudessa silmukassa lauseet evaluoidaan 2 x 4 kokoisissa (iteraatioavaruuden) lohkoissa samanaikaisesti Kuten kaikissa silmukoissa, joissa on iteraatioiden välisiä riippuvuuksia täytyy reunaehto (boundary condition) olla määritelty, eli iteraatiot joiden riippuvuudet vievät silmukassa käytävän iteraatioavaruuden ulkopuolelle pitää olla määriteltyjä (ts. muuttujilla näiden riippuvuuksien alkupäässä on jokin määritetty alkuarvo)
Muunnetussa silmukassa suoritetaan 8 (= 4 x 2) operaatiota samanaikaisesti, mikä antaan kahdeksan kertaisen suoritusnopeuden Riippuvuusvektorien tarkempi analyysi kertoo, että silmukan suoritusaikaa voidaan edelleen pienentää soveltamalla valikoitua kutistamista (selective shrinking): tämä tarkoittaa, että usein riittä uloimman silmukan kutistaminen ja muuntaa sisemmät silmukan DOALL-rakenteeksi (=rinnakkaiseksi) Edellisessä esimerkissä riittää ulomman silmukan kutistaminen: j iteraatiot suoritetaan samanaikaisesti Tämä on mahdollista, koska uloimman silmukan kutistaminen hoitelee riippuvuuden oikein automaattisesti: do i1 = 3, n, step 2 doall i = i1, i1+1 doall j = 5,m a(i,j) = b(i-3,j-5) b(i,j) = a(i-2,j-4) all all i d1 2 d2 j
Silmukan keskinäisvaihto (loop interchange) silmukoiden järjestys vaihdetaan: pidetään huoli, että koodin oikeellisuus säilyy esim. edellisessä esimerkissä vaihtamalla sisä- ja ulkosilmukka keskenään saadaan kutistustekijää suurennettua kahdesta neljään, mikä mahdollistaa enemmän rinnakkaisuutta Silmukan keskinäisvaihto on sallittu toimenpide, jos uudet riippuvuusvektorit pysyvät positiivisina Esim. seuraava silmukka ei sovellu keskinäisvaihtomuunnokseen: do i = 1,n do j = 1,n a(i,j) = a(i-1,j+1) + b(i-2,j) d = [1-1] i j Jos silmukat i ja silmukka j vaihdetaan keskenään, riippuvuusvektorista tulee negatiivinen, mikä tarkoittaa, että oikea suoritusjärjestys menetetään: riippuvuusvektori osoitaa menneisyyteen ts. muuttujan käyttäjä on menneisyydessä, eli tuottaja on myöhässä Huom: riippuvuusvektori on negatiivinen, jos sen osoittaa siitä indeksiavaruuden pisteestä missä muuttuja luotiin, pienempään käyttäjän pisteeseen ( menneisyyteen )
Kuva 3.12: Riippuvuudet esimerkissä 3.11 suoritusjärjestys jos silmukat vaihdetaan keskenään: riippuvuuksia rikotaan, koodi ei toimi oikein d = [-1 1] (j,i)-avaruudessa muunnoksen jälkeen
Seuraavassa esimerkissä (esim. 3.12) silmukat voidaan vaihtaa: do j = 1,n do i = 1,n a(i,j) = a(i-1,j) + b(i-2,j) Silmukka vastaa toiminnaltaan seuraavaa silmukaa: do i = 1,n do j = 1,n a(i,j) = a(i-1,j) + b(i-2,j)
Kuva 3.13: datariippuvuudet esimerkissä 3.12 indeksi J voidaan vektoroida muunnoksen jälkeen: voidaan laskea saman aikaisesti, koska ei riippuvuuksia J iteraatioiden välillä
Seuraavassa esimerkissä (esim. 3.13) tarkastellaan useampi indeksistä silmukkaa: do i = 0,9 do j = 0,9 do k = 0,9 a(i,j) = a(i,j) + b(i,k) * c(j,k) Silmukan lauseeseen voidaan täydentää puuttuvat indeksit: a(i,j,k) = a(i,j,k-1) + b(i,j,k) * c(i,j,k) Silmukassa esiintyy yksi riippuvuusvektori d = (0,0,1) T, mistä nähdään, että riippuvuudet ovat indeksin k suunnassa: silmukkaa k ei voida suorittaa rinnakkain Vaihtamalla silmukoiden k ja i järjestystä voidaan j- ja i-silmukka suorittaa samanaikaisesti (ei riippuvuuksia (i,j)-tasossa) Silmukan suoritus nopeutuu 100 kertaisesti (10x10x10 10)
Silmukan yhdistäminen (loop fusion) Tekniikkaa käytetään yhdistämään kaksi peräkkäistä silmukkarakennetta yhdeksi silmukaksi Datariippuvuuksien määrittelemää laskentajärjestystä ei saa rikkoa esim. seuraavat silmukat voidaan yhdistää do i = 1,n S1: a(i) = b(i) + c(i+1) do i = 1,n S2: c(i) = a(i-1) Silmukaksi: do i = 1,n S1: a(i) = b(i) + c(i+1) S2: c(i) = a(i-1) koska datariippuvuus suhteita ei rikota yhdistetyssä silmukassa
Seuraavia silmukoita ei voida yhdistää: do i = 1,n S1: a(i) = b(i) + c(i+1) S1 do i = 1,n S2: c(i) = a(i+2) S2 sillä yhdistäminen: do i = 1,n S1: a(i) = b(i) + c(i+1) S2: c(i) = a(i+2) S1 S2 muuttaisi lauseen S2 datariippuvuuden lauseesta S1 (1. silmukasta) epäriippuvuudeksi S2:sta S1:een (S2 lukee muuttujan ennen sen tuottamista lauseessa S1) t............ t silmukka 1 silmukka 2 yhdistetty silmukka
Silmukan yhdistämistä käytetään normaaleissa kääntäjissä vähentämään silmukoiden aiheuttamaa yleisrasitetta (overhead) Silmukan yhdistäminen vähentää myös DOALL silmukoiden tapauksessa silmukan alustamiseen liittyviä rasitteita: alustus täytyy tehdä vain kerran
Silmukan purku (loop collapsing) Silmukan purku yhdistää kaksi sisäkkäistä silmukka yhdeksi silmukaksi Tekniikkaa voidaan hyödyntää, kun riippuvuuksien määräämää laskentajärjestystä ei rikota Tekniikka muuntaa silmukan yksiulotteiseksi määrittelemällä muuttujien indeksi käytetyn indeksin funktioina Esim: do i = 1,4 do j = 1,5 a(i,j) = a(i,j-1) 3 voidaan kirjoittaa muodossa do k = 1,20 i = roof(k/5) j = k mod 5 a(i,j) = a(i,j-1) 3 Huom! kirjan esimerkeissä kirjan tekijä on käyttänyt mod-operatiota siten, että a mod a = a, eli esim. 5 mod 5 = 5, eli x mod 5 = 1,2,3,4,5,1,2,3,..., kun x = 1,2,3,4,5,6,7,8,...
Silmukan jakaminen Eräät ohjelmat voidaan jakaa itsenäisiksi (tai lähes itsenäisiksi) yksinkertaisemmiksi ohjelmiksi Jakaminen voi johtaa laskentaan käytetyn ajan lyhenemiseen Jakamistapa voidaan johtaa analysoimalla laskennallisten osasten riippuvuuksia: mitä vähemmän riippuvuuksia osien välillä, sitä paremmin jakaminen on tehty
Esim: do i = 1,m a(i) = a(i-2) 3 Silmukassa on yksi riippuvuus d = 2 Koska d > 1, voidaan silmukka jakamalla muodostaa kaksi itsenäistä prosessia, jotka suorittavat itsenäisesti oman osan ohjelman suorituksesta: prosessi 1: do i = 1,floor( (m-1)/2 ) * 2 + 1, step 2 a(i) = a(i-2) 3 prosessi 2: do i = 2,floor(m/2) * 2 + 1, step 2 a(i) = a(i-2) 3 esim. d1 = 3 ja d2 = 6 gcd = 3 kolme prosessia: sininen, punainen ja vihreä (askelkoko 3) Silmukka voidaan jakaa g kappaleeseen itsenäisiä osia, missä g on riippuvuusvektorien (pituuden) suurin yhteinen jakaja (gcd): jos g löytyy se tarkoittaa, että itsenäiset prosessit voidaan toteuttaa silmukoina joilla on vakio askelkoko (=gcd) ja etenemällä tällä askelkoolla, riippuvuudet toteutuvat oikein
Indeksijoukkojen ja riippuvuuksien muunnokset Perusajatus on muuntaa indeksi joukkoja ja datariippuvuuksia käyttäen matemaattisia funktioita siten, että alkuperäisiä riippuvuuksia ei rikota ja ohjelman suoritus tehostuisi Kyseessä on globaalimuunnos: indeksijoukko järjestetään uudelleen ja samalla riippuvuudet Sisäkkäiset silmukan ovat hyvin yleisiä algoritmeissa ja ohjelmissa
Termejä Indeksijoukko: algoritmin n-ulotteista indeksijoukko merkitään J n : algoritmissa esiintyy tällöin n-kertaa sisäkkäinen silmukka Jokainen piste tässä n-ulotteisessa avaruudessa on erillinen algoritmiin liittyvä laskentapiste Indeksiavaruuden muoto määräytyy silmukoissa käytettyjen indeksien arvoalueista: esim. kolmen indeksin tapauksessa kunkin indeksin arvoalueen ollessa vakio indeksiavaruus on suuntaissärmiö k j i
Riippuvuusvektorit: matriisin D muodostavat riippuvuusvektorit on määriteltyjä indeksiavaruudessa: niiden lähtöpiste ja kohdepiste on indeksiavaruuden pisteitä Jokaiseen indeksiavaruuden pisteeseen voidaan assosioida riippuvuusvektori(t), joka lähtee ko. pisteestä Jokaiseen indeksiavaruuden pisteeseen voidaan myös assosioida muuttuja(t) jotka tuotetaa ko. pisteessä Indeksiavaruudessa on pisteitä jotka vastaanottavat dataa riippuvuusvektorien kautta toisista pisteistä Indeksiavaruudessa on myös pisteitä joissa tuotetaan muuttujia ja joista tuotettuja muuttujia haetaan toisiin pisteisiin riippuvuusvektoreita pitkin
Suoritusjärjestys: algoritmin kannalta äärimmäisen olennainen käsite; kertoo missä järjestyksessä indeksijoukon pisteet suoritetaan Oikea suoritus järjestys on sellainen, joka ei riko algoritmissa esiintyviä riippuvuuksia Oikeita suoritusjärjestyksiä voi olla useita Sekventiaalisessa algoritmissa indeksipisteet käydään läpi yksi kerrallaan Rinnakkaisalgoritmissa muodostetaan yhteensopivien indeksipisteiden ryhmiä: jokainen ryhmä voidaan laskea samanaikaisesti
Indeksijoukon muunnoksen periaate on löytää funktio, joka muuntaa sekventiaalisesti järjestetyn indeksijoukon uudeksi joukoksi, jonka järjestys soveltuu rinnakkaislaskentaan Esim. 3.14: katsotaan seuraavaa algoritmia: for i = 1 to n for j = 1 to n for k = 1 to n S1: a(i,j,k) = a(i-1,j+1,k) * b(i-1,j,k+1) S2: b(i,j,k) = b(i-1,j-1,k+2) + b(i,j-3,k+2) end k end j end i Indeksiavaruus on J 3 = {(i,j,k); 1 i, j, k n} Jokaisessa em. indeksiavaruuden pisteessä tapahtuu laskentaa: kertolasku ja yhteenlasku Jokaisessa em. indeksiavaruuden pisteessä tuotetaan myös kaksi muuttujaa a(i,j,k) ja b(i,j,k), joiden tuottamiseen käytetään algoritmista löytyvien riippuvuusvektoreiden alkupäistä haettuja arvoja (aikaisemmin tuotettuja arvoja)
Riippuvuudet on määritetty tuotettujen ja käytettujen muuttujien välillä: neljä riippuvuusvektoria tässä tapauksessa d1 = (1,-1,0) T parille ( a(i,j,k), a(i-1,j+1,k) ) d2 = (1,0,-1) T parille ( b(i,j,k), b(i-1,j,k+1) ) d3 = (1,1,-2) T parille ( b(i,j,k), b(i-1,j-1,k+2) ) d4 = (0,3,-2) T parille ( b(i,j,k), b(i,j-3,k+2) ) Riippuvuusmatriisi saa muodon: D = d1 [ d d d ] 1 2 3 d4 1 1 1 0 = 1 0 1 3 0 1 2 2 a b b b i j k
Määritelmä 3.1: T on validi muunnosfunktio, joka muuntaa algoritmin A algoritmiksi A jos: 1. Algoritmi A on syöte-ulostuloekvivalentti algorimin A kanssa; 2. T on bijektio (yksi-yhteenkuvaus) ja monotoninen funktio, joka on määritelty indeksijoukossa J n ; 3. A :n indeksijoukko on A:n muunnettu indeksijoukko, eli J n = T(J n ); ja 4. A :n riippuvuudet ovat A:n muunnetut riippuvuudet, eli D = T(D) Tarkoitus on yrittää etsiä sellainen T, jolla A :n suoritusaika olisi merkittävästi lyhempi kuin A:n suoritusaika Koska T on bijektio ja monotoninen funktio (ei-vähenevä) indeksijoukossa, niin d > 0 tarkoittaa että d = T(d) > 0, eli muunnos T säilyttää datariippuvuudet (suoritusjärjestyksen)
Ositetaan muunnos T kahdeksi funktioksi siten, että ensimmäinen huolehtii ensimmäisistä k:sta indeksistä ja toinen lopuista n k indeksistä: missä kuvaus π on määritely seuraavasti: π: J n J k tai π(i 1,i 2,...,i n ) = (i 1, i 2,...,i k ) ja kuvaus S on määritely seuraavasti S: J n J k tai S(i 1,i 2,...,i n ) = (i k+1, i k+2,...,i n ) funktioiden π ja S ulottuvuuden määrittelee k, joka on pienin arvo siten, ettäπyksi määrittelee A :n suoritusjärjestyksen ts. varmistaa muunnetun algoritmin syöteulostuloekvivalenttisuuden k ensimmäistä indeksiä voidaan ajatella aikakoordinaateina ja loppuja avaruuskoordinaatteina: aikakoordinaatit antavat suoritusjärjestyksen ja avaruuskoordinaatit määrittelevät (kullekkin aikakoordinaatille) pisteryhmän, joka voidaan suorittaa samanaikaisesti (esim. eri prosessoreissa) Aikakoordinaatteja käytetään ajallisen suorituskyvyn muunteluun ja avaruuskoordinaatteja tiedonsiirrollisen suorituskyvyn muunteluun T Π = S
Kaikki indeksijoukon J n elementit I joille π(i) on vakio voidaan suorittaa samanaikaisesti: ensimmäiset k muunnettua koordinaattia ovat tällöin vakio ja määritelmän mukaan ne edustavat aikaa, eli näille elementeille laskenta-ajanhetki on sama joten ne voidaan suorittaa myös rinnakkain π(i) = vakio edustaa hypertasoja jotka sisältävät pisteitä joilla ei ole datariippuvuuksia Avaruuskoordinaattimuunnos valitaan siten, että muunnetut koordinaatit soveltuvat hyvin laskentaa tekevän rinnakkaistietokoneen tiedonsiirtorakenteeseen
Lineaariset muunnokset Oletetaan, että ohjelmassa on n sisäkkäistä silmukkaa ja m vakioriippuvuusvektoria (ts. eivät muutu ajon aikana) Riippuvuusvektorit muodostavat matriisin D = [d1,d2,...,dm], jonka koko on n x m Etsitään lineaarinen muunnos T siten, että I = TI Koska T on lineaarinen, niin T(I+d j ) T(I) = T(d j ) = d j, kun 1 j m Tämä voidaan kirjoittaa muotoon: TD = D, missä D = [d 1,d 2,...,d m] edustaa J n :n muokattuja riippuvuusvektoreita
Oletetaan, että halutaan valita D siten, että uusi algoritmi täyttää annetut vaatimukset T on olemassa jos em. yhtälöllä on ratkaisu ja ratkaisu koostuu kokonaisluvuista Seuraava teoreema osoittaa tarvittavat ja riittävät ehdot validille lineaariselle muunnokselle: voidaan käyttää työkaluna esivalittaessa D Määritelmä: kongruenttisuus (congruence) Jos kahden kokonaisluvun a ja b erotus on jaollinen luvulla p, niin a:n ja b:n sanotaan olevan kongurentteja, mikä kirjoitetaan a b mod p kongruenttisuus sanoo, että a mod p = b mod p Esim. 7 2 mod 5, 13-3 mod 8
Jos a ja b ovat vektoreita kongruenttisuus määritellään: jos c on vektorin b elementtien suurin yhteinen jakaja niin a ja b ovat kongruentteja, kun a i b i mod c, i = 1,...,n. Eli, ai on jaollinen c:lla kaikilla i = 1,..,n (b i on määritelmän mukaan jaollinen c:llä ja jos a i mod c = b i mod c täytyy a i :n olla myös jaollinen c:llä, eli a i mod c = b i mod c = 0)
Teoreema 3.1: Tarvittavat ja riittävät ehdot algoritmin validin muunnoksen T olemassa ololle, kun algoritmilla on vakio riippuvuusmatriisi D, ovat: 1. d j d j mod c j ; i j m, missä m on riippuvuusvektorien lkm. ja c i on alkuperäisen riippuvuusvektorin d j elementtien suurin yhteinen jakaja 2. Jokaisen vektorin d j ensimmäinen elementti, joka ei ole nolla, arvo on positiivinen Ensimmäinen ehto kertoo, että uuden riippuvuusvektorin elementit ovat jaollisia alkuperäisen vektorin elementtien suurimmalla yhteisellä jakajalla, joka on kokonaisluku: tämä on tarvittava ehto sille, että T voidaan ratkaista kokonaisluvuille (eli T koostuu kokonaisluvuista) yhtälöllä TD = D on validi ratkaisu Toinen ehto kertoo, ettäπd j > 0, eli T säilyttää suoritusjärjestyksen muunnetussa algoritmissa
Esim: tutkitaan silmukkaa jolla on riippuvuusmatriisi: D = [ ] = d 1 d 2 d1:n suurin yhteinen jakaja on 1 ja d2:n 2 d1:n kongruentti on vektori d 1, jonka elementit muodostaa mikä tahansa seuraavien rivien elementtien kombinaatio (ykkösellä jaolliset luvut):... -2-1 0 1 2 3...... -2-1 0 1 2 3... Vastaavasti d2:n kongruenttin d 2 muodostaa mikä tahansa seuraavien rivien elementtien kombinaatio (kakkosella jaolliset luvut):...-4-2 0 2 4 6......-4-2 0 2 4 6... Valitaan: D = 3 2 4 2 ' 1 2 [ d 1 d ] ' = ' 2 1 0
Yhtälöstä D = TD tunnetaan D ja D ja T voidaan laskea: T = D D -1 1 1 T = 1 2 D voidaan valita eri tavoin joten muunnoksia T on useita: yleensä pyritään löytämään muunnos, joka minimoi rinnakkaislaskenta-ajan ja tiedonsiirron määrän (tiedonsiirtoreittien kompleksisuuden)
Optimaaliset aikamuunnokset Rinnakkaisalgoritmissa laskenta pyritään järjestämään ryhmiksi siten, että kaikki laskenta yhden ryhmän sisällä voidaan suorittaa samanaikaisesti: tälläinen ryhmä edustaa rinnakkaislaskennan aika-askelta Ryhmien lukumäärä edustaa täten laskentaan käytettyä kokonaisaikaa Rinnakkaislaskenta-askelten määrä (rinnakkaisaika) voidaan määritellä: aika = (lopetusaika aloitusaika)/siirtymä + 1 missä siirtymä on minimiaika kahden askeleen välissä (kuva 3.14) sisältäen aika-askeleella tehtyyn laskentaan käytetyn ajan ja seuraavalle askeleelle siirrettyjen muuttujien välittämiseen käytetty aika Yksinkertaisuuden vuoksi oletetaan, että ainoastaan ensimmäinen muunnetun algoritmin koordinaateista liittyy aikaan, eli k = 1: tämä tarkoittaa, että esim. 3-ulotteisessa indeksiavaruuden tapauksessa, pyrimme etsimään 2-ulotteisia tasoja joilla laskenta voidaan tehdä samanaikaisesti (eli jäljelle jäävät kaksi ulottuvuutta edustavat hetkellisiä muuttujien arvoja tai fyysisiä laskentayksiköitä tietyllä ajan hetkellä) Tästä seuraa, että muunnos π on muotoa 1 x n (eli 1 x k matriisi tai rivivektori): ts. etsimme vektoria, joka on tasojen normaalin suuntainen ja jonka projektio riippuvuusvektoreille on positiivinen (varmistaa suoritusjärjestyksen säilymisen) Indeksiavaruuden pisteiden projektio π:lle antaa aikakoordinaatin ja projektio on sama niille pisteille, jotka voidaan suorittaa samanaikaisesti
Kuva 3.14: rinnakkaislaskenta-aika
Algoritmin muunnos säilyttää suoritusjärjestyksen, jos πd j > 0, eli riippuvuusvektorit säilyvät positiivisina (=datariippuvuudet säilyvät muuttujien välillä) Tuotetun ja käytetyn muuttujan välinen aikaero (askelissa) on täsmälleen πd j muuttujalle jolla on riippuvuus d j Jokainen riippuvuus voi johtaa eri aikaeroon Algoritmin siirtymä määritellään pienimpänä aikaerona (askeleina) minkä tahansa kahden laskennan välillä: dispπ = min{πd j }, j = 1,...,m aloitusajan ja lopetusajan välinen aikaero on max(πi 2 ) - max(πi 1 ) = max π(i 2 I 1 ), missä I 2 on viimeisellä askeleella laskettava piste ja I 1 on ensimmäisellä askeleella laskettava piste Tästä seuraa, että rinnakkasilaskenta-aika on: t π = 1 + ceil(max π(i 2 I 1 )/ dispπ)
Optimaalinen aikamuunnos saavutetaan, kun t π minimoidaan: tämä on vaikea ongelma Esim. 3.15: johdetaan optimaalinen π esimerkissä 3.14 esitetylle ohjelmalle, eli etsimme muunnosta t Π T = = t S t 11 21 31 t t t 12 22 32 t t t 13 23 33 Kun muunnosta π käytetään riippuvuusvektoreihin saadaan seuraavat ehdot: πd 1 > 0 t 11 t 12 > 0 πd 2 > 0 t 11 t 13 > 0 πd 3 > 0 t 11 + t 12-2 t 13 > 0 πd 1 > 0 3t 12 2t 13 > 0 On olemassa useita mahdollisia aikamuunnoksia π jotka täyttävät ehdot: asetetaan hatusta vedetty ehto jolla rajataan muunnosten lukumäärää: 3 t1 i 3 i= 1
Asetetulla ehdolla pyritään pitämään muunnosmatriisin elementtien arvot pieninä, jolloin muunnetut riippuvuudet pysyvät lyhyinä (yksinkertaistaa mm. vaadittavaa tiedonsiirtoverkkoa prosessoreiden välillä) Taulukko 3.1 esittää viisi eri aikamuunnosta jotka täyttävät ehdot:
Taulukossa 3.1 ensimmäinen sarake esittelee löydetyt aikamuunnokset, toinen sarake näyttää muunnetun riippuvuusmatriisin (tästä nähdään aikasiirtymä kunkin muuttujat/riippuvuuden tuottamisen ja käyttämisen välillä), kolmas sarake kertoo algoritmin aloituspisteen, missä X on don tcare, eli on olemassa useita pisteitä joille aikamuunnos antaa saman arvon (X johtuu muunnoksessa olevista nollista): aloituspisteessä aikamuunnos antaa pienimmän arvon neljäs kertoo algoritmin lopetuspisteen, jossa aikamuunnos antaa suurimman arvon, ja viides sarake kertoo tarvittavien rinnakkaislaskenta askelien määrän: π 5 on paras aikamuunnos jolle t = (2N 1) (2 N)/2 + 1 = (3N 3)/2 = (3N 1)/2 lopetus aloitus
Kuva 3.15 näyttää indeksiavaruuden ja π 5 määrittelemät tasot π 5 I = vakio, eli kaikki ne pisteet joille π 5 I on sama voidaan suorittaa saman aikaisesti (eli ne sijaitsevat samalla tasolla jonka normaali on yhdensuuntainen π 5 :n kanssa) Koska riippuvuusvektoreilla on π:n suuntainen komponentti, säilyvät ne muunnoksessa positiivisina, eli riippuvuusvektorien projektio π:lle on positiivinen: tästä seuraa, että siirryttäessä tasolta seuraavalle riippuvuusvektorien suunnassa, seuraavalla tasolla olevien pisteiden projektio π:lle täytyy kasvaa, ts. projektio π:lle toimii aikakoordinaattina kasvaen riippuvuuksien suunnassa Saavutettu nopeutus on 2N 3 /(3N-1)
Kuva 3.15: Indeksijoukko ja π 5 :n määrittelemät hypertasot π 5 I = vakio Tason pisteet I projosoituvat siten, ettäπ 5 I = vakio, eli π 5 on tason normaalin suuntainen π 5 = (2,0,-1)