INF2440 Uke 8, v2016 : Om Oblig 3 - radixsortering, Ulike Threadpools, JIT-kompilering. Arne Maus PSE, Inst. for informatikk

Like dokumenter
INF2440 Uke 9, v2017 : Om Oblig 3 - radixsortering, Ulike Threadpools, JIT-kompilering. Arne Maus PSE, Inst. for informatikk

7) Radix-sortering sekvensielt kode og effekten av cache

INF2440 Uke 8, v2015 : Om Oblig 3, Ulike Threadpools, JIT-kompilering. Arne Maus PSE, Inst. for informatikk

INF2440, Uke 3, våren2015 Regler for parallelle programmer, mer om cache og Radix-algoritmen. Arne Maus OMS, Inst. for informatikk

INF2440 Uke 4, våren2014 Avsluttende om matrisemultiplikasjon og The Java Memory Model + bedre forklaring Radix. Arne Maus OMS, Inst.

INF2440, Uke 3, våren2014 Regler for parallelle programmer, mer om cache og Radix-algoritmen. Arne Maus OMS, Inst. for informatikk

UNIVERSITETET I OSLO

INF2440 Uke 4, v2017 Om å samle parallelle svar, matrisemultiplikasjon og The Java Memory Model + evt bedre forklaring Radix

INF2440 Uke 4, v2015 Om å samle parallelle svar, matrisemultiplikasjon og The Java Memory Model + evt bedre forklaring Radix

INF2440 Uke 12, v2014. Arne Maus OMS, Inst. for informatikk

INF2220 høsten 2017, 12. okt.

UNIVERSITETET I OSLO

INF2440 Uke 11, v2014 om parallell debugging og Goldbachs problem, om Oblig 3. Arne Maus OMS, Inst. for informatikk

INF2440 Prøveeksamen, løsningsforslag, 20 mai Arne Maus PSE, Inst. for informatikk

INF2440 Uke 6, våren2014 Mer om oppdeling av et problem for parallellisering, mye om primtall + thread-safe. Arne Maus OMS, Inst.

INF3030, Uke 3, våren 2019 Regler for parallelle programmer, mer om cache og Matrise-multiplikasjon. Arne Maus / Eric Jul PSE, Inst.

I et Java-program må programmøren lage og starte hver tråd som programmet bruker. Er dette korrekt? Velg ett alternativ

INF2440 Eksamen 2016 løsningsforslag. Arne Maus, PSE ifi, UiO

Prøveeksamen INF2440 v Arne Maus PSE, Inst. for informatikk

UNIVERSITETET I OSLO

INF2440 Uke 5, våren2015 Om oppdeling av et problem for parallellisering, mye om primtall + thread-safe. Arne Maus PSE, Inst.

UNIVERSITETET I OSLO

INF2440 Uke 7, våren2017. Arne Maus PSE, Inst. for informatikk

UNIVERSITETET I OSLO

Parallellprogrammering og Sortering INF nov. 2015

INF2440 Uke 10, v2018 : Arne Maus PSE, Inst. for informatikk

INF NOV PARALLELL SORTERING. Arne Maus, PSE, Ifi

Arne Maus OMS, Inst. for informatikk

INF2220 høsten 2016, 9. nov.

INF2440 Uke 8, v2017. Arne Maus PSE, Inst. for informatikk

INF2440 Uke 7, våren2015. Arne Maus PSE, Inst. for informatikk

INF2440 Uke 13, v2015. Arne Maus PSE, Inst. for informatikk

INF2440 Uke 9, v2014 : Arne Maus OMS, Inst. for informatikk

INF2440 Uke 11, v2015 om parallell debugging og Goldbachs problem, om Oblig 2,3 og 4. Arne Maus PSE, Inst. for informatikk

INF2220 høsten 2015, 5. nov.

INF2440 Effektiv parallellprogrammering Uke 2 -, våren tidtaking. Arne Maus PSE, Inst. for informatikk

INF2220 høsten 2017, 19. okt.

UNIVERSITETET I OSLO

Fig1. Den konvekse innhyllinga av 100 tilfeldige punkter i planet (de samme som nyttes i oppgaven.)

INF2440 Uke 11, v2017 om Goldbachs problem og Oblig 2,3. Arne Maus PSE, Inst. for informatikk

INF2440 Uke 10, v2017 : Arne Maus PSE, Inst. for informatikk

INF2440 Uke 5, våren2017. Arne Maus PSE, Inst. for informatikk

INF2440 Uke 9, v2015 : Arne Maus PSE, Inst. for informatikk

INF2440 Uke 5, våren2016. Arne Maus PSE, Inst. for informatikk

INF2220: Time 12 - Sortering

IN3030 Uke 12, v2019. Eric Jul PSE, Inst. for informatikk

INF2440 Uke 10, v2015 : Arne Maus PSE, Inst. for informatikk

Kap 19. Mer om parallelle programmer i Java og Kvikksort

INF2440 Uke 10, v2014 : Arne Maus OMS, Inst. for informatikk

IN1010. Fra Python til Java. En introduksjon til programmeringsspråkenes verden Dag Langmyhr

INF2440 Uke 15, v2014 oppsummering. Arne Maus OMS, Inst. for informatikk

Løsnings forslag i java In115, Våren 1996

INF Notater. Veronika Heimsbakk 10. juni 2012

INF2440 Uke 14, v2015. Arne Maus PSE, Inst. for informatikk

INF2440 Uke 13, v2014. Arne Maus OMS, Inst. for informatikk

i=0 Repetisjon: arrayer Forelesning inf Java 4 Repetisjon: nesting av løkker Repetisjon: nesting av løkker 0*0 0*2 0*3 0*1 0*4

Forelesning inf Java 4

Løsningsforslag ukeoppg. 6: 28. sep - 4. okt (INF Høst 2011)

UNIVERSITETET I OSLO

INF2440 Uke 15, v2015 oppsummering. Arne Maus PSE, Inst. for informatikk

INF2440 Uke 15, v2017 litt om parallellisering av Oblig4 + oppsummering av kurset. Arne Maus PSE, Inst. for informatikk

Løsningsforslag for Obligatorisk Oppgave 2. Algoritmer og Datastrukturer ITF20006

INF2440 Uke 10, v2016 : Arne Maus PSE, Inst. for informatikk

INF 1000 høsten 2011 Uke september

INF1000 undervisningen INF 1000 høsten 2011 Uke september

Array&ArrayList Lagring Liste Klasseparametre Arrayliste Testing Lenkelister

INF1000 : Forelesning 4

INF2440 Effektiv parallellprogrammering Uke 1, våren Arne Maus PSE, Inst. for informatikk

i=0 i=1 Repetisjon: nesting av løkker INF1000 : Forelesning 4 Repetisjon: nesting av løkker Repetisjon: nesting av løkker j=0 j=1 j=2 j=3 j=4

Uke 8 Eksamenseksempler + Ilan Villanger om studiestrategier. 11. okt Siri Moe Jensen Inst. for informatikk, UiO

Array&ArrayList Lagring Liste Klasseparametre Arrayliste Testing Lenkelister Videre

INF Uke 10. Ukesoppgaver oktober 2012

Forelesning inf Java 5

UNIVERSITETET I OSLO

Forelesning inf Java 5

UNIVERSITETET I OSLO

INF1000: noen avsluttende ord

Java PRP brukermanual

INF1010, 22. mai Prøveeksamen (Eksamen 12. juni 2012) Stein Gjessing Inst. for Informatikk Universitetet i Oslo

Sortering med tråder - Quicksort

UNIVERSITETET I OSLO

INF2440 Effektiv parallellprogrammering Uke 1, våren Arne Maus PSE, Inst. for informatikk

Forkurs INF1010. Dag 2. Andreas Færøvig Olsen Tuva Kristine Thoresen

Oversikt. INF1000 Uke 1 time 2. Repetisjon - Introduksjon. Repetisjon - Program

MER OM PARALLELLE PROGRAMMER I JAVA OG KVIKKSORT

Liste som abstrakt konsept/datatype

INF2220: Forelesning 1. Praktisk informasjon Analyse av algoritmer (kapittel 2) (Binær)trær (kapittel )

Kap 2: Løkker og lister

INF1010 Sortering. Marit Nybakken 1. mars 2004

Innhold uke 4. INF 1000 høsten 2011 Uke 4: 13. september. Deklarasjon av peker og opprettelse av arrayobjektet. Representasjon av array i Java

INF1000 EKSTRATILBUD. Stoff fra uke 1-5 (6) 3. oktober 2012 Siri Moe Jensen

UNIVERSITETET I OSLO

INF1000 (Uke 5) Mer om løkker, arrayer og metoder

Jentetreff INF1000 Debugging i Java

Norsk informatikkolympiade runde

2 Om statiske variable/konstanter og statiske metoder.

INF110 Algoritmer og datastrukturer TRÆR. Vi skal i denne forelesningen se litt på ulike typer trær:

INF1010 Tråder II 6. april 2016

LITT OM OPPLEGGET. INF1000 EKSTRATILBUD Stoff fra uke September 2012 Siri Moe Jensen EKSEMPLER

INF1000: Forelesning 7

Transkript:

INF Uke 8, v : Om Oblig - radixsortering, Ulike Threadpools, JIT-kompilering Arne Maus PSE, Inst. for informatikk

Om inf våren Gruppetimer denne uka, men ikke neste uke eller. påskedag (8. mars) Ukeoppgaver for uke8/9 legges ut senere i dag. Obliger: Oblig (primtallsfaktorisering) leveres 8. mars Oblig (RadixMulti) legges ut 8. mars og leveres.april Oblig (konveks innhylling) legges ut. april og leveres. mai Neste forelesning er da. april

Hva har vi sett på i uke 7. Svar på et oblig-spørsmål. Hvordan parallellisere Oblig - alternativer. Model-kode for sammenligning av kjøretider på (enkle) parallelle og sekvensielle algoritmer.. Hvordan lage en parallell løsning ulike måter å synkronisere skriving på felles variable med eksempel: oblig.. Ulike strategier for å dele opp et problem for parallellisering:

Hva skal vi se på i uke 8:. Om oblig generell Radix-sortering (MultiRadix) Dette er en variant av Radix-sortering som automatisk prøver å finne ut hvor mange sifre den skal sortere på ut fra verdien av max. (- sifre) og kaller Radix-metoden tilsvarende antall ganger. Meget rask. Dere får sekvensiell versjon, skal parallelliser denne, skrive rapport osv.. En effektiv Threadpool? Executors.newFixedThreadPool. FinnMax / et enkelt problem og JIT/kompilering. Mer om effektivitet og JIT-kompilering!. Om problem(?) mellom long og int

Oblig legges ut på fredag Parallelliser Radix-sortering med et variabelt antall sifre (MultiRadix) Bytter om på array-pekere for at den mest sorterte arrayen alltid er i det som pekes på av int [] a. Kopierer alt til den arrayen som ble brukt i kallet hvis odde antall sifre brukes i sorteringa. Skriv rapport om speedup for n=,,, mill., mill og mill. MultiRadix består av to metoder, begge skal parallelliseres (men ikke en evt. array-kopiering på slutten av første metode). Den første, finn max(a[]) løst tidligere Den andre har tre steg løses i parallell effektivt: a) tell hvor mange det er av hvert sifferverdi i a[] i count[] b) legg sammen verdiene i count[] til pekere til b[] c) flytt tallene fra a[] til b[] sortert på siffer i. Steg a) blir løst i ukeoppgave 8/9 (hvor bla. hver tråd har sin kopi av count[])

Den første av to algoritmer som MultiRadix består av. int [] radixm(int [] a) { long tt = System.nanoTime(); // - digit radixsort of : a[] int max = a[], numbit =, numdigits, n =a.length; int [] bit ; // a) finn max verdi i a[] for (int i = ; i < n ; i++) if (a[i] > max) max = a[i]; while (max >= (L<<numBit) )numbit++; // antall bit i max // bestem antall bit i numbits sifre numdigits = Math.max(, numbit/num_bit); // NUM_BIT =, 7, 8 eller 9 bit = new int [numdigits]; int rest = numbit%numdigits, sum =;; radixm radixsort radixsort // fordel resten av bitene vi skal sortere paa jevnt for (int i = ; i < bit.length; i++){ bit[i] = numbit/numdigits; if ( rest-- >) bit[i]++; } int[] t, b = new int [n]; // (forts)

for (int i =; i < bit.length; i++) { radixsort( a,b,bit[i], sum); // i-te siffer fra a[] til b[] sum += bit[i]; // bytt om arrayer (bare pekere) t = a; a = b; b = t; } if (bit.length%!= ) { // et odde antall sifre, kopier innhold tilbake til original a[] (som nå er b) System.arraycopy (a,,b,,a.length); } double tid = (System.nanoTime() -tt)/.; System.out.println("\nSorterte "+n+" tall paa:" + tid + "millisek."); testsort(a); return a; } // end radix void testsort(int [] a){ for (int i = ; i< a.length-;i++) { if (a[i] > a[i+]){ System.out.println("SorteringsFEIL på plass: "+i + " a["+i+"]:"+a[i]+" > a["+ (i+)+"]:"+a[i+]); return; } } }// end enkel sorteringstest 7

radixm radixsort radixsort /** Sort a[] on one digit ; number of bits = masklen, shiftet up shift bits */ static void radixsort ( int [] a, int [] b, int masklen, int shift){ int acumval =, j, n = a.length; int mask = (<<masklen) -; int [] count = new int [mask+]; // b) count=the frequency of each radix value in a for (int i = ; i < n; i++) count[(a[i]>>shift) & mask]++; // c) Add up in 'count' - accumulated values for (int i = ; i <= mask; i++) { j = count[i]; count[i] = acumval; acumval += j; } // d) move numbers in sorted order a to b for (int i = ; i < n; i++) b[count[(a[i]>>shift) & mask]++] = a[i]; }// end radixsort 8

) Om JIT-kompilering, finn Max-verdi i en array av 8 int, Modell-kode med tråd-pool Sekvensiell og parallell kjørt ganger M:\INFPara\FinnMax>java FinnM 8 8 Kjoering:, ant kjerner:8, anttraader:8 Max verdi parallell i a:788, paa:.7887 millisek. Max verdi sekvensiell i a:788, paa:.9 millisek. Kjoering:, ant kjerner:8, anttraader:8 Max verdi parallell i a:788, paa:.8 millisek. Max verdi sekvensiell i a:788, paa:.98 millisek. Kjoering:, ant kjerner:8, anttraader:8 Max verdi parallell i a:788, paa:.97 millisek. Max verdi sekvensiell i a:788, paa:.9 millisek. Median sequential time:.9, median parallel time:.8, n= 8, Speedup:., ant iterasjoner: Min sequential tid:.98ms, max sequential tid:.9ms Min parallell tid:.97ms, max parallell tid:.7887ms, n= 8, max/min sek:., n= 8, max/min para:. 9

) Om JIT-kompilering, finn Max-verdi i en array av 8 int, Modell-kode med tråd-pool, g iterasjoner edian sequential time:., median parallel time:.7, n= 8, Speedup:.8, ant iterasjoner: in sequential tid:.ms, max sequential tid:.ms in parallell tid:.978ms, max parallell tid:.89ms, n= 8, max/min sek:., n= 8, max/min para:. Median sequential time:.8, median parallel time:.7, n= 8, Speedup:., ant iterasjoner: Min sequential tid:.ms, max sequential tid:.98ms Min parallell tid:.8ms, max parallell tid:.9ms, n= 8, max/min sek:.8, n= 8, max/min para:. Median sequential time:., median parallel time:.7, n= 8, Speedup:.9, ant iterasjoner: Min sequential tid:.ms, max sequential tid:.8ms Min parallell tid:.77ms, max parallell tid:.ms, n= 8, max/min sek:., n= 8, max/min para: 9.7

Oppsummering JIT Meget store hasthets-forbedringer av JIT-kompilering Speedup ikke mulig på små eksempler som n =8 Prøver vi f.eks n= 8mill får vi grei speedup (se nedenfor), men ikke med iterasjon Median sequential time:.7, median parallel time:.89, n= 8, Speedup:.7, ant iterasjoner: Min sequential tid:.8ms, max sequential tid:.99ms Min parallell tid:.9ms, max parallell tid:.9ms, n= 8, max/min sek:.7, n= 8, max/min para: 7.8 Hvorfor er forholdet max/min mindre her?

) En effektiv Threadpool? Vi har med modell-koden selv startet en samling av k tråder som- venter til vi vil kjøre ett problem (evt. flere ganger): enten med samme n for å få bedre tider (median) eller for en ny n. Ideen om å lage en samling av tråder som er klar for å løse neste oppgave har vi også i Java-biblioteket. Vi skal her se på: Executors.newFixedThreadPool i java.util.concurrent. Her kan vi også bytte ut problemet

Grunnidéene i Executors.newFixedThreadPool Du starter opp et fast antall tråder Hvis du under kjøring trenger flere tråder enn de startet må du vente til en av dem er ferdig og da er ledig For hver tråd som gjør noe er det tilknyttet et objekt av klassen Future: Den sier deg om tråden din er ferdig Du kan legge deg og vente på ett eller alle Future-objekter som join() med vanlige tråder Future-objektet bringer også med seg svaret fra tråd når den er ferdig, hvis den har noen returverdi En tråd som har terminert kan straks brukes på nytt fordi main-tråden venter ikke på tråden, men på tilhørende Future

For å administrere en slik mengde (pool) av tråder Må man først lage en pool (med tilhørende Vektor av Futures): class MinTraadpool{ MinTraadpool pt = new MinTraadpool (); int anttraader = Runtime.getRuntime().availableProcessors(); ExecutorService pool = Executors.newFixedThreadPool(pt.antTraader); List <Future> futures = new Vector <Future>(); Hvordan lage trådene og slippe dem ned i poolen (svømmebasenget): for (int j =; j < anttraader; j++) { Thread QParExec = new Thread(new FindExec(j)); futures.add(pool.submit(qparexec)); // submit starter trtåden }

For å administrere en slik mengde (pool) av tråder Slik venter man på framtider (Futures) get returnerer svaret (hvis noe ikke her) while (!futures.isempty()) { Future top = futures.remove(); try { if (top!= null) top.get(); } catch (Exception e) { System.out.println("Error Futures");} } Trådene som startes er vanlige (indre) klasser med en parallell metode run() : class FindExec implements Runnable { int index; public FindExec(int ind) { index = ind; } public void run() { <kall parallell metode> }}

Mange muligheter med slike pooler: Man kan lukke poolen: pool.shutdown(); Man kan lage ca. ulike typer av pooler: Fast størrelse, variabel størrelse, cachete (gjenbruk), med tidsforsinkelse, med og uten ThreadFactory (et objekt som lager tråder når det trengs),.. Det hele koker ned til spørsmålene: Vi trenger å ha en rekke tråder som parallelliserer problemet vårt Er en slik trådpool effektiv?

&)Test på effektivitet tre implementasjoner av parallell FindMax i :int [] a speedup: a) Med ExecutorService og FixedThreadPool a)med like mange tråder som kjerner: a) Med x tråder som kjerner b) Med modell kode med CyclicBarrier for start&vent n a)pool x a) Pool x b) Barrier..7,9.9,,.,,.9,99,.,,9.,,97 Konklusjon: Om lag like raske!? 7

) Radix-sortering sekvensielt kode og effekten av cache Dels er denne gjennomgangen av vanlig Radix-sortering viktig for å forstå en senere parallell versjon. Dels viser den effekten vi akkurat så tilfeldig oppslag i lageret med korte eller lange arrayer b[] i uttrykk som a[b[i]] kan gi uventede kjøretider. Ideen bak Radix er å sortere tall etter de ulike sifrene de består av og flytte de frem og tilbake mellom to arrayer a[] og b[] slik at de stadig blir sortert på ett siffer mer. I multiradix varierer (øker vi) antall sifre vi sorterer med at etter hvor mange bit det er i max-tallet i a[] 8

Om høyre, minst signifikant siffer først Radix Radix-sortering, fast eller variablet antall sifre: R: Radix-sortering med ett siffer R: Radix-sortering med to sifre R: Radix-sortering med tre sifre MultiRadix variabelt antall Alle består av to metoder: radix,radix, radix multiradix som: Først regner ut max-verdien i a[]. Så regnes ut noen konstanter som antall bit i det/de sifrene a[] skal sorteres med. Deretter kalles metoden radixsort for hvert siffer det skal sorteres etter radixm radix radix radix radixsort radixsort radixsort radixsort radixsort radixsort radixsort radixsort 9

a count... m - Figure. The use of array count in any radix algorithm when sorting on a digit with numbit bits. The illustration is after sorting. We see that there are two elements in a[] with the value on that digit, elements with value,,and element with value numbit -.

Forklaring av: count[(a[i]>> shift) & mask]++; del Tar det innenfra og ut; a[i]>> shift Ethvert ord i lageret består a -ere og -ere (alt er binært) Java har flere skift-operasjoner feks.: a[i]>>b betyr: skift alle bit-ene i a[i] b antall plasser til høyre og fyll på med b stk -er på venstre del av a[i]. a[i]<<b betyr: skift alle bitene i a[i] b antall plasser til venstre og fyll på med b stk -er på høyre del av a[i]. De bit-ene som skiftes ut av a[i] går tapt i begge tilfeller. a<< er det samme som a*, a<< er det samme som a*, a<<k er det samme som a* k Ett element i a[]: bit masklen shift mask = masklen ere

Forklaring av: count[(a[i]>> shift) & mask]++; del Java har flere bit-logiske operasjoner, for eksempel & (og): a & b er et tall som har -ere der både a og b har en -ere, og resten er. Eks: a& = et tall som er null over alt unntatt i bit som har samme bit-verdi som bit i a. Vi kan betrakte b som en maske som plukker ut de bitverdiene i a hvor b har -ere. Poenget er at: (a[i]>> shift) & mask er raskeste måte å finne hvilken verdi a[] har for et gitt siffer (sifferverdien) : Først skifter vi bit-ene i a[i] ned slik at sifferet vi er interessert i ligger helt nederst til høyre. Så &-er vi med en maske som bare har -ere for så mange bit vi har i det sifferet vi er interessert i nederst (og ellers). count[(a[i]>> shift) & mask] er da det elementet i count[] som har samme indeks som sifferverdien i a[i]. Det elementet i count[] øker vi så med (++ operasjonen)

Eksempel (shift = og mask =7) vi vil ha dre siffer a[i] = 7 (i 8-tallsystemet)=.. a[i] >> =.. (a[i] >>) &.. =.. = Vi kan velge fritt hvor lange (antall bit) sifre og hvor mange sifre vi vil ha sortere på, men summen av antall bit i sifrene vi sorterer på må være større eller lik antall bit i max, det største tallet i a[]. Et godt valg er å ha en øvre grense på bit-lengden av et siffer f.eks =, og da heller ta så mange sifre det trengs for å sortere a[].

Stegene i en radix-sortering radix,, eller MultiRadix: Finn maks verdi i a[] og bestem antall sifre med mer. FinnMax har vi parallellisert radixsort (en gang for hvert siffer): a) Tell opp hvor mange det er i a[] med de ulike mulige sifferverdiene på dette sifferet. b) Adder sammen verdiene til en array som sier hvor vi skal flytte et element i a[] med en gitt sifferverdi. c) Flytt elementene fra a[] til b[] slik at de minste verdier kommer øverst,..osv d) Kopier b[] tilbake til a[] (trenges ikke i radix,radix,..) Stegene a, b og c skal vi senere parallellisere (d kan fjernes)

Hva viser dette om cachen? manglende caching av data for Radix gir lengere kjøretider Radix med ganger så lang kode som Radix går jevnt over - ganger så fort når n>! Radixmed ganger så lang kode som Radix går ganger så fort når n > mill.

Radix-sortering den sekvensielle algoritmen Vi aksepterer at vi forrige gang greide å finne verdien av et siffer i a[]: (a[i]>> shift) & mask regner ut sifferverdien av et siffer i a[i] som : Har ett eller flere sifre til høyre for seg (mindre signifikante) som til sammen i sum har shift bit Mask inneholder så mange -ere nederst som det er bit i det sifferet vi vil finne nå og er ellers. Anta at vi skal sortere denne a[] på to sifre, a 7 7

Høyre, minst signifikant siffer først sortering på to sifre: Radix som vi nå bruker Radix-sortering, nå siffer: Radix: Radix-sortering på to sifre Radix bestås av to metoder: radix som først regner ut max-verdien i a[]. Så regnes ut noen konstanter, som antall bit i de to sifrene a[] skal sorteres med. Deretter kalles metoden radixsort for hvert av de to sifrene (dvs. to ganger) radix radixsort radixsort 7

Stegene i en radixsort: a) Tell opp i en array count slik at count[k] = hvor mange ganger k er en sifferverdi a[]. Eks. hvor mange tall i a[] = i dette sifferet? b) Legg sammen antallene i count slik at count[k] sier hvor i b[] vi skal plassere første element i a[] vi finner med sifferverdien k c) Finn sifferverdien i a[k] og flytt a[k] til b[] der count[sifferverdien] sier a[k] skal være. Øk count[sifferverdien] med til neste plass i b[] 8

Radix-sortering steg a) første, bakerste siffer Vi skal sorterere på siste siffer med bit sifferlengde (tallene -7) a) Tell opp sifferverdier i count[]: a 7 7 7 Før telling: count 7 Etter telling: count

Radix-sortering steg b) finne ut hvor sifferverdien skal plasseres De a[i] ene som inneholder j hvor skal de flyttes sortert inn i b[]? - Hvor skal -erne stare å flyttes, -erne,.osv b) Adder opp sifferverdier i count[]: Før addering: Etter addering : count count 7 7 b Kan også sies sånn: Første -er vi finner plasserer vi b[], første -er i b[] fordi det er stk -ere og de må først. -erne starter vi å plassere i b[] fordi stk -ere og stk -ere må før -erne,.osv.

Radix-sortering på det første (minst signifikante), mest høyre siffer a c) flytt a[k] til b[] der count[s] peker, hvor s= sifferverdien i a[k], øk count[s] med. 7 7 Før flytting 7 count Før flytting b Etter flytting b 7 7

Så sortering på siffer (det lengst til venstre) fra b[] til a[], trinn a) og b) b 7 7 Etter telling på siffer : 7 count Etter addering : count 7 a

Så sortering på siffer fra b[] til a[] trinn c) b 7 7 Etter telling på siffer : 7 count Etter addering : count 7 7 a 7

Situasjonen etter sortering fra b[] til a[] på siffer Etter flytting b 7 7 count 7 7 a 7 7 a[] er sortert!

) Nok et problem/overraskelse med JIT-kompilering Som vi husker går JIT-kompilering i flere steg: Oversettelse til maskinkode av hyppig brukt kode Mer bruk optimalisering av den maskinoversatte koden Si bruk > ganger Enda mer bruk super-optimalisering av koden en gang til Først noen resultater; sammenligning av Barrier-løsningen av FinnMax med samme løsning skrevet litt annerledes: Speedup: n b) Barrier Ny Barrier,9,,,,,7,,,9 7,9,97 9,8

Konklusjon: Hurra, en mye bedre parallellisering? Speedup:,97 < 9,8!!! En klart bedre løsning? At speedup er mye større, er det da sikkert at parallelliseringen er mye bedre/raskere? Svar: JA, men bare hvis den sekvensielle koden som parallelliseringen sammenlignes med er den samme. Det eneste som var forskjellig mellom disse to programmene var at jeg hadde forsøkt å gjøre den sekvensielle koden raskere ved å inline - selve koden på kallstedet. Den parallelle koden var den samme. Vi tester og ser etter hva som har skjedd her!

Hva var forskjellen mellom de to Barrier-kodene for n = Fra b) Barrier programmet (>java FinnBarrier.java): Median parallel time :.977 Median sequential time:.88,, Speedup:.98, n = Fra Ny Barrier-programmet (INFPara\FinnMax>java FinnM ): Max verdi parallell i a:99989, paa:.997 millisek. Max verdi sekvensiell i a:99989, paa:.9 millisek. Median sequential time:.99, median parallel time:.8, n=, Speedup: 9.8 Konklusjon: Det er særlig den sekvensielle kjøretiden er langsommere, ikke at den parallelle er raskere. 7

Hva var forskjellen mellom de to kodene UTEN JITkompilering, n = (java Xint BarrierMax..)? Fra b) Barrier programmet: Median parallel time:.779 Median sequential time:77.8, Speedup:., n = Fra Ny Barrier-programmet: Max verdi parallell i a:99989, paa:.8 millisek. Max verdi sekvensiell i a:99989, paa:.8 millisek. Median sequential time:.878, median parallel time:.89, n=, Speedup:.9 Konklusjon: Det er særlig den sekvensielle kjøretiden som er bedre optimalisert, ca.x for b) mens bare ca. x for NyBarrier! Hvorfor? 8

Her er forskjellen mellom de to programmene Ny Barrier, langsom (x) sekvensiell optimalisering. Koden for sekvensiell metode er lagt rett inn i en større metode (utfor() ) som ikke kalles mange ganger b) Barrier, mye raskere sekvensiell x optimalisering.laget en metode av sekvensiell kode som kalles fra utformetoden. // sekvensiell finnmax t = System.nanoTime(); totalmax = ; for (int i=;i < a.length;i++) if (a[i] > totalmax) totalmax = a[i]; t = (System.nanoTime()-t); seqtime[j] =t/.; int dosequentialversion(int [] a) { int max= -; for (int i = ; i< a.length; i++) if (a[i] > max) max = a[i]; return max; } // end dosequentialversion Optimalisatoren i JIT ser ut til å være langt bedre til å optimalisere (små) metoder enn en løkke inne i en større metode. 9

Observasjon JIT-kompilering/optimalisering Vi bør ta hensyn til hvordan optimalisatoren virker Generelt ser den ut til å greie å øke hastigheten på interpretert kode med x Små metoder som vi finner i klassen for en bit array for pimtall implementer i en byte-array (med metoder som isprime(i), setnotprime(), nextprime(m), ) og : int dosequentialversion(int [] a) i FinnMax er meget velegnet for optimalisering Så små metoder kan optimaliseres i vårt tilfelle: 77/= x Når vi skriver kode bør vi bruke denne kunnskapen fordi Gir enklere kode lettere å skrive Gir raskere kode Grunnen til dette er vel at ved at når programmereren har lagt kode inn i en metode, sier hun at avhengigheten til resten av programmet er begrenset, grovt sett til parameterne. Lettere da å optimalisere! Oppskrift: Best optimalisering hvis en metode bare behandler parameterne og lokale variable i metoden.

) Problemer med forholdet mellom long og int Java prøver hele tiden å være mest økonomisk når den regner ut uttrykk: Regner ut billigst først og så konverterer ved tilordning. public static void main (String [] args) { int m = ; long tall = m*m; System.out.println("M:"+m+", tall (m*m):"+ tall); tall = (long)m*m; System.out.println("M:"+m+", tall((long)m*m):"+ tall); tall = (long)(m*m); System.out.println("M:"+m+", tall((long)(m*m):"+ tall); tall = (long)m*(long)m; System.out.println("M:"+m+", tall((long)m*(long)m):"+ tall); } M:, tall (m*m):-7 M:, tall((long)m*m): M:, tall((long)(m*m):-7 M:, tall((long)m*(long)m):

Hva har vi sett på i uke 8:. En første gjennomgang av Oblig Den sekvensielle løsningen m. tips. En effektiv Threadpool? Executors.newFixedThreadPool. Mer om effektivitet og JIT-kompilering!. Om et problem mellom long og int