Presentasjon lastes. Vennligst vent

Presentasjon lastes. Vennligst vent

Eric Jul PSE Inst. for informatikk

Liknende presentasjoner


Presentasjon om: "Eric Jul PSE Inst. for informatikk"— Utskrift av presentasjonen:

1 Eric Jul PSE Inst. for informatikk
INF3030 Uke 7, våren 2019 Eric Jul PSE Inst. for informatikk

2 Hva så vi på i uke 6 Eratosthenes sil Kokker og Kelnere
Concurrency: De første to av tre måter å programmere monitorer i Java eksemplifisert med to løsninger av problemet: Kokker og Kelnere (eller generelt: produsenter og konsumenter) med sleep() og aktiv polling. med monitor, synchronized methods , wait>() og notify(),.. med Lock og flere køer (Condition-køer) (I dag!)

3 Plan for uke 7 Piazza – use it – if you are OK with it. NOT REQUIRED.
Mere om synkronisering og kokkene og kelnere Sil igjen Hvilken orden O() har Eratosthenes Sil ? Faktorisering av tall Alternativer for å parallellisere: Eratosthenes Sil Generelt om last-balansering ved parallellisering med eksempel.

4 Problemet vi nå skal løse: En restaurant med kokker og kelnere og med et varmebord hvor maten står
Vi har c Kokker som lager mat og w Kelnere som server maten (tallerkenretter) Mat som kokkene lager blir satt fra seg på et varmebord (med TABLE_SIZE antall plasser til tallerkener) Kokkene kan ikke lage flere tallerkener hvis varmebordet er fullt Kelnerne kan ikke servere flere tallerkener hvis varmebordet er tomt Det skal lages og serveres NUM_TO_BE_MADE antall tallerkener

5 Restaurant versjon 1: varmelampe … c Kokker (produsenter)
TABLE_SIZE Lager tallerken-retter Serverer tallerken numOnTable c Kokker (produsenter) w Kelnere (konsumenter) 9/7/2019

6 3) Om monitorer og køer (tre eksempler på concurrent programming)
3) Om monitorer og køer (tre eksempler på concurrent programming). Vi løser synkronisering mellom to ulike klasser. Først en aktivt pollende (masende) løsning med synkroniserte metoder (Restaurant1.java). Aktiv venting i en løkke i hver Kokk og Kelner + at de er i køen på å slippe inn i en synkronisert metode Så en løsning med bruk av monitor slik det var tenkt fra starten av i Java (Restaurant2.java). Kokker og Kelnere venter i samme wait()-køen + i køen på å slippe inn i en synkronisert metode. Til siste en løsning med monitor med Lock og Condition-køer (flere køer – en per ventetilstand (Restaurant9.java) Kelnere og Kokker venter i hver sin kø + i en køen på å slippe inn i de to metoder beskyttet av en Lock .

7 Først en aktivt pollende (masende) løsning med synkroniserte metoder (Restaurant1.java)
Dette er en løsning med en kø, den som alle tråder kommer i hvis en annen tråd er inne i en synkronisert metode i samme objekt. Terminering ordnes i hver kokk og kelner (i deres run-metode) Den køen som nyttes er en felles kø av alle aktive objekter som evt. samtidig prøver å kalle en av de to synkroniserte metodene get og put. Alle objekter har en slik kø. synchronized boolean getPlate(..) synchronized boolean putPlate(..) HeatingTable Kø av objekter som venter på å utføre en av de synkroniserte metodene.

8 Løsning 2: Javas originale opplegg med monitorer og to køer.
Den originale Java løsningen med synkroniserte metoder og en rekke andre metoder og følgende innebygde metoder: sleep(t): Den nå kjørende tråden sover i ‘t’ millisek. notify(): (arvet fra klassen Object som alle er subklasse av). Den vekker opp en av trådene som venter på låsen i inneværende objekt. Denne prøver da en gang til å få det den ventet på. notifyAll(): (arvet fra klassen Object). Den vekker opp alle de trådene som venter på låsen i inneværende objekt. De prøver da alle en gang til å få det de ventet på. wait(): (arvet fra klassen Object). Får nåværende tråd til å vente til den enten blir vekket med notify() eller notifyAll() for dette objektet.

9 notify()

10 Løsning 2, All venting er inne i synkroniserte metoder i en to køer.
All venting inne i to synkroniserte metoder Kokker and Kelnere venter på neste tallerken i wait-køen Vi må vekke opp alle i wait-køen for å sikre oss at vi finner en av den typen vi trenger (Kokk eller Kelner) som kan drive programmet videre Ingen testing på invariantene i run-metodene 9/7/2019

11 3) En parallell løsning med Doug Lea’s Conditions.
Bruker to køer: En for Kokker som venter på en tallerkenplass på bordet En for Kelnere som venter på en tallerken Da trenger vi ikke vekke opp alle trådene, Bare en i den riktige køen. Kanskje mer effektivt Klart lettere å programmere 9/7/2019

12 final Lock lock = new ReentrantLock();
final Condition notFull = lock.newCondition(); // kø for Kokker final Condition notEmpty = lock.newCondition(); // kø for Kelnere public boolean putPlate (Kokker c) throws InterruptedException { lock.lock(); try {while (numOnTable == MAX_ON_TABLE && numProduced < NUM_TO_BE_MADE){ notFull.await(); // waiting for a place on the table } if (numProduced < NUM_TO_BE_MADE) { numProduced++; numOnTable++;; notEmpty.signal(); // Wake up a waiting Kelner to serve if (numProduced == NUM_TO_BE_MADE) { // I have produced the last plate, notEmpty.signalAll(); // tell Kelnere to stop waiting, terminate notFull.signalAll(); // tell Kokker to stop waiting and terminate return false; return true; } else { return false;} } finally { lock.unlock(); } } // end putPlate

13 public boolean getPlate (Kelnerw) throws InterruptedException {
lock.lock(); try { while (numOnTable == 0 && numProduced < NUM_TO_BE_MADE ) { notEmpty.await(); // This Kelner is waiting for a plate } if (numOnTable > 0) { numOnTable--; notFull.signal(); // Signal to one Kokk in the Kokker’s waiting queue return true; } else { return false;} } finally { lock.unlock(); } // end getPlate En Kelner eller en Kokk blir signalisert av to grunner: - for å behandle (lage eller servere) en tallerken til - ikke mer å gjøre, gå hjem (tøm begge køene)

14 Vurdering av de tre løsningene
Løsning 1: Enkel, men kan ta for mye av CPU-tiden. Særlig når systemet holder av andre grunner å gå i metning vil typisk en av trådene da bli veldig treige, og da tar denne løsningen plutselig ½-parten av CPU-tiden. Løsning 2: God, men vanskelig å skrive Løsning 3: God, nesten like effektiv som løsning 2 og lettere å skrive.

15 Avsluttende bemerkninger til Produsent-Konsument problemet
Invarianter brukes av alle programmerere (ofte ubevisst) program, loop or metode (sekvensiell eller parallell) Å si dem eksplisitt hjelper på programmeringen HUSK: synchronized/lock virker bare når alle trådene synkroniserer på samme objektet. Når det skjer er det sekvensiell tankegang mellom wait/signal Når vi sier notify() eller wait() på en kø, vet vi ikke: Hvilken tråd som starter Får den tråden det er signalisert på kjernen direkte etter at den som sa notify(), eller ikke ??. Ikke definert Debugging ved å spore utførelsen (trace) – System.out.println(”..”) Skriving utenfor en Locket/synkronisert metode/del av metode, så lag en: synchronized void println(String s) {System.out.println(s);} Ellers kan utskrift bli blandet eller komme i gal rekkefølge.

16 Hoare’s Original Monitors and Conditions
Review of Hoare’s article

17 Om sil og faktorisering
Eratosthenes sil Vi krysser av i en bit-tabell. Husk det er ‘bare’ ikke-primtallene vi finner ved avkryssingen (primtallene er de som står igjen etter all nødvendig avkryssing) (Det er ikke mulig å effektivt finne primtallene direkte! Ingen formel for primtallene!) Faktorisering av M: Vi dividerer M med alle primtall < N i E-Silen for N = 𝑀 Finner vi en faktor f i M , fortsetter vi med faktorisering av M’ = M/f;

18 Quick Review of Erastophene’s Sieve
Review of crossing off

19 Hvor mange ganger krysser vi av i Eratosthenes Sil for alle primtall < N = 𝑀 ?
Hvordan vet vi hvor mange kryss som settes med ES? Se på faktoriseringa: Vi ser at de største tallene har ( ) ulike faktorer som ikke er 2, er = 3,5 i snitt – si 4. Hver slik ulike faktor i tallet t < 𝑀 tilsvarer 1 avkryssing av pi (eller en mindre faktor pj ) < 2 𝑁 (= 4 𝑀 ) sekv: = 107* sekv: = 2*2*3*5*5*89*1447*1553* sekv: = 19*2897* sekv: = 2* * sekv: = 3*101*241* sekv: = 2*2*2*2*2*1061* sekv: = 5*7*13* sekv: = 2*3*3*17*31* sekv: = * sekv: = 2*2*11*168409* sekv: = 3*2713* sekv: = 2*5* sekv: = 167*659*3581*86629*117163 sekv: = 2*2*2*3*7*7*4127*669869* sekv: = 239*

20 Hvilken orden har Eratosthnes Sil – algoritmen (N)
Vi krysser av for alle primtall < 𝑁 - hvor mange er det? svar: omlag: 𝑁 log⁡( 𝑁 ) Hvor mange kryss settes av pi mellom pi2 og N ? svar: omlag 𝑁−𝑝𝑖 / (2* 𝑝𝑖 )< 𝑁 4 Et øvre estimat for (antall primtall)* (antall kryss per primtall)= O(N) = 𝑁 log⁡( 𝑁 ) * 𝑁 4 = 𝑁 𝑁 log⁡( 𝑁) = 2∗𝑁 𝑁 log⁡(𝑁) = 𝑵 𝑵 𝒍𝒐𝒈⁡(𝑵)

21 Factorizing Numbers How to factorize number

22 Om å parallelliser Sil og Faktorisering, Riktig og Raskere
Eratosthenes sil Vi krysser av i en bit-tabell. Hvordan gjøre dette i parallell Hva det er vi deler opp, hva gjør hver tråd? Skal vi kopiere noen data til hver tråd? Hva er felles data og hva er lokale data i hver tråd. Faktorisering av M: Vi dividerer M med alle primtall i E-Silen fra 0: 𝑀 Parallelliseringen av faktorisering: Hvordan dele opp : Primtallene ? Tallene fra 0: M ?

23 Riktig og Raskere – Eratosthenes Sil
Mulig problem E-sil : Hvis to tråder setter av kryss samtidig i en byte, kan det da gå galt? byte[i] = byte[i] & xxxx; // problem ? Hvordan blir dette utført i kjernen Må vel da synkronisere ? Raskere: Antall synkroniseringer må ikke bli for stort Antall tråder ganger (evt * 2,3,4) : Helt OK Log (N) ganger, evt log(N)*ant tråder: OK, 𝑁 tja ? (hvor stor %-andel er 𝑁 av N, N=100, N=10 000) ikke :N = 𝑀 eller M ganger

24 Alternativ 1 for Eratosthenes Sil
Dele opp primtallene mellom trådene så hver tråd tar noen hver og krysser av i hele Sila: Ulempe: 3 og 5 genererer langt de fleste kryssene (lastbalansering) Kunne la tråd0 ta 3, tråd1 ta 5 , osv Problem: to ulike primtall krysser av ulike steder i samme byte – kan da vel miste ett av kryssene (eks: 3 kryssser 51, 7 krysser 49) Avkryssing er 3 opersjoner: Last opp i register , &-operasjon, lagre tilbake To primtall krysser av for det samme tallet (eks. 7 og 5 krysser av 105) – da taper vi vel (?) ingen ting om ett av kryssene går tapt. Hvis alle trådene har sin kopi av Sila, skulle dette gå OK. Må da tilslutt ‘slå sammen’ disse k stk byte-arrayene . Tiden det tar å slå sammen disse vil kanskje bli ‘lang’ ??

25 Alternativ 2 for Eratosthenes Sil:
Dele opp tallene i Sila : tallene 0:N mellom trådene, Kan ikke dele helt likt – skillet må gå mellom to byter Hvorfor (?) Hver tråd krysser av med alle aktuelle primtall på sin del av Sila. Problem 1: Hvor starter avkryssingen av primtall p i hver tråds (første) byte. Problem 2: Hvordan vet trådene som har området: low..high hvilke primtall den skal krysse av for?? Hvilke er det ? Svar : alle primtall < 𝑁 eller ℎ𝑖𝑔ℎ Hvordan lage og lagre dem først? Tre alternativer: Tråd0 lager dem først (sekvensiell del – jfr. Amdahls lov) Alle trådene lager de samme primtallene < 𝑁 i en lokal kopi Se på dette rekursivt som et problem som kan parallelliseres (dvs . Sekvensiell fase : Først alle primtall < 𝑁 som så lager primtall < 𝑁 )

26 Grep 2 – vi lager noen ekstra data
I FinnMax-problemet hadde vi først: en lokal variabel: lokalMax som hver tråd lokalt oppdaterte til de var ferdige; og så kalte hver tråd en global synkronisert metode som evt. satte ny verdi i globalMax Kan vi prøve noe tilsvarende her. I løsning a) trenger alle trådene primtallene < 𝑁 . Skisse - enten: a1) Tråd-0 lager disse primtallene først i tabellen mens de andre trådene venter, eller a2) Alle trådene lager hver sin lokale tabell over disse primtallene a3) Enten a1) eller a2), så krysser hver tråd deretter av i sin del av bit-arrayen for alle disse primtallene. N.B. Hvis a1) skal tråd-0 bare bruke disse ‘små’ primtallene til først å krysse av i området opp til 𝑁 , ikke i hele sitt område.

27 Billig å lage en slik liten start-tabell for trådene i alt. a)
Eks: skal vi parallelt krysse av for primtall < 2 milliarder, trenger denne tabellen plass til 2 𝑚𝑟𝑑 = bit/16= 2796 byter for å finne de primtallene p < (og i den lille tabellen trenger vi bare krysse av med primtall q < = 212 for å finne dem. Billig start på å parallellisere det å finne alle primtall < ). tallene vi skal faktorisere 1 M 1 N = 𝑀 Primtallene vi da trenger 1 p = 𝑁 den lille tabellen 44 722 trenger da primtall 1..q 1 q = 𝑝 212

28 Faktorisering alt 3: Primtallene 0:N deles likt ut en etter en etter tur
Alle trådene tar hver k’te primtall Anta at k=4 Tråd0 tar: 3, 13,... Tråd1 tar: 5, 17,... Tråd2 tar: 7, 19,... Tråd3 tar: 11, 23,... Fordeler Med de andre alternativene: Hvis vi finner f.,eks at 13 er en faktor, så har tråd 1,2 og 3 ikke mer å gjøre (og tråd0 gjør resten av arbeidet) Ulempe Hvor raskt er det stadig for en tråd å finne neste k’te primtall i tabellen Kan vi organisere primtallene slik at det går raskere ?

29 3) Generelt om last-balansering og ‘ekstra’ lokale data
Vitsen er at alle trådene har om lag like mye å gjøre (tidsmessig), eller sagt på en annen måte: Vi prøver å optimalisere slik at den tråden som fullfører sist gjør det raskest mulig. Når vi skal parallellisere er det (nesten) alltid en array eller matrise vi skal regne/gjøre noe med: Vi kan enten dele opp selve arrayen (i like store deler 1/k –del til hver av de k trådene) – dvs. dele opp indeksene radvis eller kolonnevis hvis det er en matrise, eller vi kan dele opp verdiene i arrayen slik at tråd-0 får de 1/k minste verdiene, tråd-1 de neste 1/k verdiene,.. osv, eller vi kan estimere arbeidsmengden og vi 1/k-del av den til hver av trådene, eller … ? .

30 Hva har vi sett på i uke 7 Piazza – please use it
Mere om synkronisering og kokkene og kelnere – demo ved tavle  Erastostenes sil review Hvilken orden O() har Eratosthenes Sil ? Faktorisering – med eksempler Hvordan lage en parallell løsning – ulike måter å synkronisere skriving på felles variable – med eksempel Ulike strategier for å dele opp et problem for parallellisering


Laste ned ppt "Eric Jul PSE Inst. for informatikk"

Liknende presentasjoner


Annonser fra Google