IN3030 Uke 12, v2019 Eric Jul PSE, Ist. for iformatikk 1
Hva skal vi se på i Uke 12 Review Radix sort Oblig 4 Text Program Parallellizig 2
Oblig 4 Radix sort Parallelliser Radix-sorterig med fra 1 5 sifre Skriv rapport om speedup for = 1000, 10 000, 100 000, 1 mill., 10 mill og 100 mill. Radix består av to metoder, begge skal parallelliseres. De første har et steg, fi max() løst tidligere De adre har tre steg løses i parallell effektivt: b) tell hvor mage det er av hvert sifferverdi i i cout[] c) legg samme verdiee i cout[] til pekere til b[] d) flytt tallee fra til b[] Steg b) er løst tidligere (hvor bla. hver tråd har si kopi av cout[]) 3
Flere tips til Oblig3 - MultiRadix Problemet med data-kokurrase: To eller flere tråder skriver samtidig på samme variabel (i++-problemet), i samme plass i e array: Løsig: Hver tråd har e kopi av disse felles variable Etter at alle trådee er ferdig (f.eks. etter e barrier-syk) ka resultatee fra hver tråd samstilles (også dette helst i parallell) til et felles svar Muliges må ma kopiere data mer e e gag? Oppdelig av data i arrayer ma skal behadle med k tråder: Dele opp arraye i like store deler (det er ideksee ma deler opp) Dele opp etter verdiee i elemetee (tråd 0 eier de miste verdiee, tråd 1 de est-miste,..,) 4
Datastrukturer og grep i Oblig4 (hvorda parallellisere) Radix består av 4 steg (løkker) flere valg for datastruktur og oppdelig ved parallelliserig a) fi max verdi i b) cout= oppttellig av ulike sifferverdier i c) Summér opp i cout[] akkumulerte verdier (pekere) d) Flytt elemeter fra til b[] etter iholdet i cout[] Geerelt skal vi se følgede tekikker med k tråder: Dele opp data i a [] i k like deler Dele opp verdiee i i k like deler => dele opp cout[] i k like deler Kopiere delte data til hver tråd her lokal cout[] kopi e eller to gager Iføre ekstra datastrukturer som ikke er i de sekvesielle løsige 5
a) fi max verdi i eies av tråd0 eies av tråd1 allmax[] it globalmax 0 1 k-1 eies av tråd k-1 Tråd-i fier max i si del av og legger svaret i allmax[i] <syc på e CyclicBarrier cb> Nå har alle trådee si max i allmax[] valg å: Skal e av trådee (f.eks. tråd-0) fie svaret og legge det i e felles globalmax (mes de adre trådee veter i så fall ok e <syc på e CyclicBarrier cb>)? Skal alle trådee hver rege ut e lokal globalmax (de får vel samme svar?) og fortsette direkte til steg b) 6
b) cout= oppttellig av ulike sifferverdier i Ata at det er 10 bit i et siffer dvs. 1024 mulige sifferverdier eies av tråd0 eies av tråd1 cout[] 0 1 allcout[] [] 0. k eies av tråd k-1 1023 Skal: 1. Hver tråd ha e kopi av cout[] 2. Eller skal cout være e AtomicItegerArray 3. Eller skal de ulike trådee gå gjeom hele og tråd-0 bare ta de små verdiee, tråd-1 de est miste verdie,..(dvs: dele verdiee mellom trådee) 7
Roadmap oversikt over drøftelse av Oblig4 flere alterativer på steg b og seere edriger i c og d Steg b1)? Steg c1) Steg d1)?? Steg b1+) Steg a)? Steg b2) Steg c2) Steg d2)? Steg b3) Steg c3) Steg d3) FiMax Tell sifferverdier lag pekere flytt til b[] 8
a) fi max verdi i eies av tråd0 eies av tråd1 allmax[] it globalmax 0 1 k-1 eies av tråd k-1 Tråd-i fier max i si del av og legger svaret i allmax[i] <syc på e CyclicBarrier cb> Nå har alle trådee si max i allmax[] valg å: Skal e av trådee (f.eks. tråd-0) fie svaret og legge det i e felles globalmax (mes de adre trådee veter i så fall ok e <syc på e CyclicBarrier cb>)? Skal alle trådee hver rege ut e lokal globalmax (de får vel samme svar?) og fortsette direkte til steg b) 9
b) cout= oppttellig av ulike sifferverdier i Ata at det er 10 bit i et siffer dvs. 1024 mulige sifferverdier eies av tråd0 eies av tråd1 cout[] 0 1 allcout[] [] 0. k eies av tråd k-1 1023 Skal: 1. Hver tråd har e kopi av cout[] 2. Eller skal cout være e AtomicItegerArray 3. Eller skal de ulike trådee gå gjeom hele og tråd-0 bare ta de små verdiee, tråd-1 de est miste verdie,..(dvs: dele verdiee mellom trådee) 10
Om delvis deklarasjoer av arrayer it allcout[] []; - da lages? it allcout[] [] = ew it [k][]; - da lages? it [] cout = ew it[10] ; allcout[k] [0] = x; 11
Løsig b1) lokale cout[] i hver tråd som etter opptellig settes i i allcout[] [] eies av tråd0 eies av tråd1 Lokal cout[] 0 1 allcout[] [] 0 1. 1023 eies av tråd k-1 1023 Hver tråd-i teller opp de ulike sifferverdie i si del av opp i si lokale cout[] som så hektes i i allcout[] [] <syc på e CyclicBarrier cb> Nå er hele opptellige av i de k cout[]-ee som heger i allcout[] [] Dee løsige treger (kaskje) et tillegg b1-b: Summerig av verdiee i allcout[][] til e felles globalcout[] 12
b1+) : Summerig av verdiee i allcout[][] til e felles: globalcout[] allcout[] [] 0 1. 1023 globalcout[] 0 1 1023 Deler opp de mulige sifferverdiee (1024) på de k trådee slik at tråd-0 for de 1024/k miste, tråd-1 de 1024/k est miste, Tråd-i summerer sie verdier (sie koloer) på tvers i de k cout[] arrayee som heger i allcout[] [], i i globalcout[] Bør allcout[][] traspoeres før summerig (mer cache-velig)?? <syc på e CyclicBarrier cb> Da er globalcout[] fullt oppdatert Spørsmål: Treger vi globalcout[], eller holder det med allcout[][]? Svar : Avheger av este steg c) 13
Løsig b2) Eller skal cout[] være e AtomicItegerArray? eies av tråd0 eies av tråd1 Felles AtomicItegerArray cout[] eies av tråd k-1 Alle tråder oppdaterer AtomicItegerArray cout[] samtidig ute fare for sykroiserigs-problemer med sifferverdiee fra si del av pga sykroiseriga av AtomicItegerArray-elemetee <syc på e CyclicBarrier cb> Spørsmål: Hvor mage sykroiseriger treger vi med dee løsige 14
Løsig b3) Eller skal de ulike trådee gå gjeom hele og tråd-0 bare ta de /k miste verdiee, tråd-1 de /k est miste verdiee,.. (dvs. dele verdiee mellom trådee) Felles it []cout Tråd-i oppdaterer cout[] bare med de verdiee som tråd-i eier ute fare for sykroiserigs-problemer med sifferverdiee fra hele ige adre skriver slike sifferverdier. <syc på e CyclicBarrier cb> Spørsmål: Hvor mage sykroiseriger treger vi med dee løsige Hvor mye av leser hver tråd 15
c1) Gitt b1: Summér opp i cout[] akkumulerte verdier (pekere) eies av tråd0 eies av tråd1 allcout[][] 0 1. 1023 o 1. k-1 it []localcout eies av tråd k-1 Fra løsig b1 Vi treger et prisipp for at hver tråd fier akkurat hvor de skal plassere si del av. Hver tråd får ok e kopi av cout[]: localcout[] iitielt tom (=0) Tråd-i si localcout[t] er lik summe av alle tråder si opptellig i allcout[r][s] for alle r og s<t + sum av allcout[r][t] for r < i år s = t Vitse er at før tråd-i plasserer sie sifferverdier s, må det først gjøres plass til alle lavere sifferverdier + de sifferverdiee i tråder med ideks midre e i. <syc på e CyclicBarrier cb> 16
c2 og c3) Summér opp i cout[] akkumulerte verdier (pekere) eies av tråd0 eies av tråd1 Setralt it [] delsum 0. k AtomicItegerArray eller Felles it []cout eies av tråd k-1 Fra løsig b2, b3 I løsig b2 og b3 har vi samme situasjo som sekvesiell løsig. Ka parallelliseres som følger :Deler verdiee i cout[] mellom de k trådee som før. Alle summerer sie verdier og legger de i e separat array delsum[k]. <syc på e CyclicBarrier cb> Deretter justerer du die plasser i cout[] med summe av delsummee i delsum[k] fra tråder med midre ideks e deg. Spørsmål: Hvor lag tid tar dette kotra at tråd-0 gjør hele jobbe og de adre veter. 17
c4+b1) Summér opp cout[][] OG juster pekere Etter b1) magler: oppsummerig af alle de lokale cout[] i et globalcout[] <syc på e CyclicBarrier cb> Justerig af globalcout[] så sum bliver til pekere. Dette ka kombieres i EN løkka, hvis ma gjør det sekvesielt i EN tråd. <syc på e CyclicBarrier cb> Sekvesiell løsig muligvis svær at gjøre raskere i parallell? Spørsmål: Hvor lag tid tar dette kotra at e tråd gjør hele jobbe og de adre veter? Prøv at rege på atallet av operatioer versus atal operatioer i adre steg. 18
d1,2 og 3) Flytt elemeter fra til b[] etter iholdet i cout[] eies av tråd0 eies av tråd1 b1: localcout[] k stk. b2, b3: it []cout b[] eies av tråd k-1 Løsig b1: Nå ka alle trådee i full parallell kopiere fordi hver localcout[] peker i i ulike plasser i b[]. Løsig b2: Alle trådee ka i full parallell kopiere over fra til b[] fordi hver gag blir sykroiserig foretatt av AtomicItegerArray. Løsig b3: Nå ka alle trådee i full parallell flytte elemeter fra til b[] fordi hver tråd bare flytter sie sifferverdier. Hver tråd går gjeom hele. Alle b1,b2,b3: <syc på e CyclicBarrier cb> Spørsmål: Hvilke av løsigee tar legst tid? 19