Rinnakkaisuus parallel tietokoneissa rinnakkaisia laskentayksiköitä concurrent asioita tapahtuu yhtaikaa Rinnakkaisuuden etuja: laskennan nopeutuminen (sarjoittuvat operaatiojonot) ilmaisuvoima (ongelman rinnakkainen luonne) Rinnakkaisuus eri tasoilla (granulariteetti) konekäskyt ohjelmointikielen lauseet prosessit (itsenäiset aliohjelmat) ohjelmat Eri tasojen rinnakkaisuus näkyy kielessä eri tavoin! Virtuaalinen ja todellinen rinnakkaisuus loogiset laskentayksiköt (prosessit) fyysiset laskentayksiköt (prosessorit) 1
1 Prosessit ja säikeet Eri ohjelmointikielissä eri terminologia Prosessi käyttöjärjestelmän tarjoama väline ohjelmien ajamiseen rinnakkain oma muistialue Kommunikointi usein käyttöjärjestelmän viestinvälityksen kautta yms. Säie (thread) kevyt prosessi peräkkäin suoritettava käskyjono, joka toimii muista säikeistä riippumatta kullakin säikeellä oma ohjelmalaskuri ja pino saman prosessin säikeillä yhteinen muistialue Kommunikointi jaetun muistin välillä, haasteena synkronointi muistin käytössä Kommunikoivat prosessit voivat olla myös eri koneissa, aliohjelman voi suorittaa eri koneessa (RPC, Remote Procedure Call) 2
2 Synkronointi Kommunikointi: viestien välitys jaettu muisti Synkronointi: implisiittistä erikoistoimenpiteitä Yhteistoiminnallinen (co-operation) synkronointi prosessi A odottaa, että prosessi B saa toimintansa päätökseen, ennen kuin A voi jatkaa suoritustaan esim. tuottaja-kuluttaja ongelma Kilpaileva (competition) synkronointi prosessit tarvitsevat samaa resurssia, jota voi käyttää vain yksi prosessi kerrallaan esim. yhteiseen muistiin kirjoittaminen condition synchr. mutual exclusion 3
Vuorottaisrutiinit (coroutines) Vanhin todellisissa ohjelmointikielissä esiintynyt rinnakkaisuuden muoto Simula67, Modula-2 Kvasirinnakkaisuus yksi prosessori prosessorin vaihdot prosessilta toiselle kuvataan eksplisiittisesti ohjelmoija hoitaa skeduloinnin 4
MODULE Program; FROM SYSTEM IMPORT PROCESS, NEWPROCESS, TRANSFER,..; VAR v1, v2, main: PROCESS; PROCEDURE P1; PROCEDURE P2; BEGIN BEGIN...... TRANSFER ( v1, v2 ); TRANSFER ( v2, v1 );...... TRANSFER ( v1, v2 ); TRANSFER ( v2, v1 );...... TRANSFER ( v1, v2 ); TRANSFER ( v2, main ); END P1; END P2; BEGIN NEWPROCESS ( P1,..., v1 ); NEWPROCESS ( P2,..., v2 ); TRANSFER ( main, v1 ); END; Vuorottaisrutiinit Modula-2:ssa 5
Algol68 PL/I Semaforit (opastimet) Skedulointiin perustuva synkronointi Mahdollistavat muiden prosessien poissulkeminen Kokonaislukumuuttujia, joilla operaatiot P (wait) ja V (signal): P ( S ): if S > 0 then S := S 1 else aseta tämä prosessi odottamaan S:ää V ( S ): if S:ää odottaa prosesseja then anna jonkin niistä jatkaa else S := S + 1 P ja V jakamattomia (atomisia) operaatioita Yleinen tai binaarinen semafori 6
Monitorit Skedulointiin perustuva synkronointi Kehittyneempiä yhteisen tiedon valvojia kuin semaforit Moduulirakenteen hyödyntäminen tiedon piilottaminen abstraktit tietotyypit Suojausmekanismi operaatioiden poissulkevuus vain yksi prosessi kerrallaan voi suorittaa moduulin operaatioita (prosessilla hallussaan monitorin lukko) Monitorin odotusjoukko toimintoja suorittamaan haluavat prosessit 7
Java (säikeet) Rinnakkaisuuden mahdollistaminen luokan Thread periminen rajapinnan Runnable toteuttaminen pääohjelmaa varten luodaan automaattisesti säie Säikeiden suoritus säikeen toiminta kirjoitetaan run-operaatioon suoritus alkaa kutsumalla start-operaatiota, jolloin järjestelmä kutsuu run-operaatiota Muita Thread-luokan operaatioita sleep: säikeen lukitseminen (millisekunteina) yield: suorituksessa oleva säie luovuttaa jäljellä olevan aikaviipaleensa 8
Java (synkronointi) Jokaisella oliolla on lukko (lock) estää synkronoitujen operaatioiden suorittamisen yhtä aikaa Kun säie kutsuu olion synkroinoitua operaatiota säie ottaa haltuunsa olion lukon, jolloin synchronized void f ( ) {... } void f ( ) { synchronized ( this ) {... } } muut säikeet eivät voi kutsua olion mitään synkronoitua operaatiota säie luopuu lukosta, kun operaatio on suoritettu loppuun tai säie siirtyy odotustilaan 9
Säikeiden (prosessien) luominen Yhdessä kielessä voi olla useita tapoja säikeiden luomiseen Yhteinen aloitus (co-begin) Rinnakkaiset silmukat (parallel loops) Esittelyiden työstämiseen liittyvä aloitus (launch-at-elaboration) Haarautumat ja liittymät (fork-join) Implisiittinen vastaaminen (implicit receipt) Aikaistettu kuittaus (early-reply) 10
Yhteinen aloitus nondeterministinen: begin a := 3, b := 4 end rinnakkainen: par begin a := 3, b := 4 end Algol68-koodia Mahdollista myös Occamissa par begin p ( a, b, c ), begin d := q ( e, f ); r ( d, g, h ) end, s ( i, j ) end p ( a, b, c ) d := q ( e, f ) s ( i, j ) r ( d, g, h ) 11
Rinnakkaiset silmukat: Esittelyiden työstämiseen liittyvä aloitus: SR: Occam: co ( i := 5 to 10 ) -> p ( a, b, i ) oc par i = 5 for 6 p ( a, b, i ) Ada: procedure P is task T is... end T; begin P... end P; Fortran95: forall ( i = 1 : n 1 ) A ( i ) = B ( i ) + C ( i ) A ( i + 1 ) = A ( i ) + A ( i + 1 ) end forall 12
Edelliset vaihtoehdot Haarautumat ja liittymät fork...... sisäkkäisyys join ei sisäkkäisyyttä 13
Haarautumat ja liittymät Ada: task type T is... begin... end T; pt: access T := new T; Java: class mythread extends Thread {... public void mythread (... ) {... } public void run ( ) {... } }... mythread t = new mythread (... ); Modula-3: t.start ( ); t := Fork ( c );... Join ( t ); t.join ( ); 14
GPU-laskenta Näytönohjaimen laskentateho merkittävä, näytönohjain ohjelmoitavissa Näytönohjaimen arkkitehtuuri erilainen kuin CPU:n Tyypillisesti vektorilaskentaa, SIMD tms. Kaikissa koneissa ei GPU:ta, ohjelman pitäisi silti toimia Halutaan yhteinen ohjelmointikieli CPU:lle ja GPU:lle Esim. Nvidian CUDA, pohjautuu C:hen 15
CUDA 16
SIMD-laskenta Single Instruction, Multiple Data Rinnakkain etenevät laskennat etenevät tarkasti samaa tahtia, mutta eri datalle Tyypillistä tieteellisessä laskennassa, jossa käsitellään matriiseja, vektoreita yms. Näkyy kielessä esim. silmukkarakenteissa yms. Prosessorien konekielessä myös tukea vektorilaskentaan (SISD=Single Instruction, Single Data) (MIMD=Multiple Instruction, Multiple Data) (SPMD=Single Program, Multiple Data) 17
Aktiiviset oliot Olio-ohjelmoinnissa olio luonnollinen rinnakkaisuuden yksikkö Aktiivisessa oliossa oma suoritussäie, joka suorittaa kutsutut metodit Kutsuja ei jää odottamaan, paluuarvot usein futuureilla Ei ongelmia jäsenmuuttujien poissulkemisen kanssa Mitä tehdä, jos jäsenmuuttujan suoritus jää odottamaan? (Mm. Symbianin akt. olio suorittaa jatkuvasti runmetodia, muut kutsut normaaleja) 18
Futuurit Jos kutsu rinnakkainen, miten välittää tulos kutsujalle, joka ei jää odottamaan? Futuurit edustavat myöhemmin saatavaa paluuarvoa Jos futuurin arvo luetaan, lukija jää odottamaan tuloksen valmistumista Futuurilta voi kysyä, onko tulos saatavilla future<int> tulos = async(f, x); // C++0x //... if (tulos.get() == 3)... // Odottaa tarvittaessa 19
Säieallas / Thread pool Joskus rinnakkaisuutta tarvitaan suorittamaan suuri määrä pikkutehtäviä Säikeen käynnistäminenkin turhan raskasta Järkevä rinnakkaisuuden määrä sama kuin fyysisesti prosessorien määrä Tehtäviä lisätään thread pooliin, joka suorittaa niitä rinnakkain järkevän määrän Tehtävien käynnistämisellä voi olla ehtoja Tehtävät usein funktioita, lambda-lausekkeita... 20
Funktionaalisuus Säikeillä yhteinen muistiavaruus, luku/kirjoitus yhteisistä muuttujista suojattava Aiheuttaa myös välimuistin synkronointitarpeen Funktionaalisissa kielissä ei sivuvaikutuksia, ongelmaa ei ole! Esim. Haskell-kääntäjä voi rinnakkaistaa laskentaa Concurrent Haskellissa kuitenkin myös säikeet ja erilliset yhteiset muuttujat kommunikointiin 21
Transaktionaalinen muisti Käytössä mm. Concurrent Haskellissa Koodilohkon suoritus atomisesti (transaktio). Kaikki muutokset näkyviin kerralla Yksi toteutustapa: Jokainen luku/kirjoitus jaettuihin muuttujiin kirjataan lokiin, itse muuttujia ei muuteta Lohkon lopussa tarkastetaan, että muuttujien arvot ovat mitä pitää Jos eivät ole, joku muu on käynyt sotkemassa! Tuhotaan loki ja yritetään uudelleen 22
Ada83 Adan tehtävät Muistuttavat pakkauksia (syntaksiltaan) määritys ja runko määrityksessä ei yksityistä osaa aktiivinen yksikkö (toisin kuin pakkaus) Tehtävien vuorovaikutus perustuu kohtaamiseen (rendezvous), joka tapahtuu porttien (entry) avulla portti määrittelee tehtävän tarjoamat palvelut ulkopuolelle palvelija ja palveltava synkroninen viestien välittäminen odottaminen passiivista 23
T1 T2 Portit ja kohtaaminen portin kutsu in out in out portti P Kohtaamislause on lause, vaikka muistuttaa proseduuria Kohtaamisen epäsymmetrisyys: kutsuvan prosessin täytyy tuntea portti portin omaava tehtävä ei tunne kutsujaa Tehtävän (portin) kutsu muodostaa kohtaamispaikan kutsuja odottaa tiettyä tehtävää portin haltija odottaa mitä tahansa tehtävää normaali parametrivälitys (in, out, in out) 24
select accept P1... end P1;... lauseita... or accept P2... end P2;... lauseita... or... end select; Portin haltija palveltavien puute jollakin portilla ei saa estää palvelua muilla porteilla valitaan sellainen portti, jolla on odottajia Valikoiva kohtaaminen (select-lause) Portin kutsuja select P (...);... lauseita... or... lauseita... end select; tietyn palvelun jääräpäinen odottaminen ei ole järkevää jos portin haltija ei ole välittömästi valmis palvelemaan, suoritetaan jokin muu toiminto 25