| @@ -0,0 +1,41 @@ | |||
| import java.util.Random; | |||
| class Main { | |||
| static int nTests = 7; | |||
| public static void main(String[] args) { | |||
| Solver sseq = new Sequential(); | |||
| Solver spar = new Parallel(); | |||
| if (args.length != 1) { | |||
| System.out.println(" bruk : >java SekvensiellRadix <n> "); | |||
| } else { | |||
| int n = Integer.parseInt(args[0]); | |||
| Timer seq = test(sseq, n); | |||
| System.out.println("Sequential: "+seq.prettyTime()); | |||
| Timer par = test(spar, n); | |||
| System.out.println("Parallel: "+par.prettySpeedup(seq)); | |||
| } | |||
| } | |||
| static Timer test (Solver s, int len) { | |||
| Random r = new Random(123); | |||
| Timer[] timers = new Timer[nTests]; | |||
| for (int i = 0; i < nTests; ++i) { | |||
| int[] a = new int[len]; | |||
| for (int j = 0; j < len; j++) { | |||
| a[j] = r.nextInt(len); | |||
| } | |||
| Timer t = timers[i] = new Timer().start(); | |||
| a = s.sort(a); | |||
| t.end(); | |||
| new MultiRadix().testSort(a); | |||
| return t; | |||
| } | |||
| return Timer.median(timers); | |||
| } // end doIt | |||
| } | |||
| @@ -5,37 +5,18 @@ import java.util.*; | |||
| * for store verdier av n > 100 m, kjør (f.eks): | |||
| * >java -Xmx16000m MultiRadix 1000000000 | |||
| ************************************************************/ | |||
| class MultiRadix{ | |||
| int n; | |||
| class MultiRadix { | |||
| int [] a; | |||
| final static int NUM_BIT = 7; // alle tall 6-11 .. finn ut hvilken verdi som er best | |||
| public static void main(String [] args) { | |||
| if (args.length != 1) { | |||
| System.out.println(" bruk : >java SekvensiellRadix <n> "); | |||
| } else { | |||
| int n = Integer.parseInt(args[0]); | |||
| new MultiRadix().doIt(n); | |||
| } | |||
| } // end main | |||
| void doIt (int len) { | |||
| a = new int[len]; | |||
| Random r = new Random(123); | |||
| for (int i =0; i < len;i++) { | |||
| a[i] = r.nextInt(len); | |||
| } | |||
| a = radixMulti(a); | |||
| } // end doIt | |||
| int [] radixMulti(int [] a) { | |||
| int [] radixMulti(int [] a, int start, int end) { | |||
| long tt = System.nanoTime(); | |||
| // 1-5 digit radixSort of : a[] | |||
| int max = a[0], numBit = 2, numDigits, n =a.length; | |||
| int max = a[start], numBit = 2, numDigits; | |||
| int [] bit ; | |||
| // a) finn max verdi i a[] | |||
| for (int i = 1 ; i < n ; i++) | |||
| for (int i = start + 1 ; i < end; i++) | |||
| if (a[i] > max) max = a[i]; | |||
| while (max >= (1L<<numBit) )numBit++; // antall binaere siffer i max | |||
| @@ -50,10 +31,10 @@ class MultiRadix{ | |||
| if ( rest-- > 0) bit[i]++; | |||
| } | |||
| int[] t=a, b = new int [n]; | |||
| int[] t=a, b = new int [a.length]; | |||
| for (int i =0; i < bit.length; i++) { | |||
| radixSort( a,b,bit[i],sum ); // i-te siffer fra a[] til b[] | |||
| radixSort(a, b, bit[i], sum, start, end); // i-te siffer fra a[] til b[] | |||
| sum += bit[i]; | |||
| // swap arrays (pointers only) | |||
| t = a; | |||
| @@ -62,24 +43,24 @@ class MultiRadix{ | |||
| } | |||
| if (bit.length%2 != 0 ) { | |||
| // et odde antall sifre, kopier innhold tilbake til original a[] (nå b) | |||
| System.arraycopy (a,0,b,0,a.length); | |||
| System.arraycopy (a,start,b,start,end - start); | |||
| } | |||
| double tid = (System.nanoTime() -tt)/1000000.0; | |||
| System.out.println("\nSorterte "+n+" tall paa:" + tid + "millisek."); | |||
| testSort(a); | |||
| return a; | |||
| } // end radixMulti | |||
| int[] radixMulti(int[] arr) { | |||
| return radixMulti(arr, 0, arr.length); | |||
| } | |||
| /** Sort a[] on one digit ; number of bits = maskLen, shiftet up 'shift' bits */ | |||
| void radixSort ( int [] a, int [] b, int maskLen, int shift){ | |||
| System.out.println(" radixSort maskLen:"+maskLen+", shift :"+shift); | |||
| int acumVal = 0, j, n = a.length; | |||
| void radixSort ( int [] a, int [] b, int maskLen, int shift, int start, int end){ | |||
| int acumVal = 0, j; | |||
| int mask = (1<<maskLen) -1; | |||
| int [] count = new int [mask+1]; | |||
| // b) count=the frequency of each radix value in a | |||
| for (int i = 0; i < n; i++) { | |||
| for (int i = start; i < end; i++) { | |||
| count[(a[i]>>> shift) & mask]++; | |||
| } | |||
| @@ -89,8 +70,9 @@ class MultiRadix{ | |||
| count[i] = acumVal; | |||
| acumVal += j; | |||
| } | |||
| // d) move numbers in sorted order a to b | |||
| for (int i = 0; i < n; i++) { | |||
| for (int i = start; i < end; i++) { | |||
| b[count[(a[i]>>>shift) & mask]++] = a[i]; | |||
| } | |||
| @@ -102,6 +84,6 @@ class MultiRadix{ | |||
| System.out.println("SorteringsFEIL på plass: "+i +" a["+i+"]:"+a[i]+" > a["+(i+1)+"]:"+a[i+1]); | |||
| return; | |||
| } | |||
| } | |||
| } | |||
| }// end simple sorteingstest | |||
| }// end SekvensiellRadix | |||
| @@ -0,0 +1,71 @@ | |||
| class Parallel implements Solver { | |||
| class Worker implements Runnable { | |||
| MultiRadix mr; | |||
| int[] arr; | |||
| int start, end; | |||
| boolean done = false; | |||
| Worker(MultiRadix mr, int[] arr, int start, int end) { | |||
| this.mr = mr; | |||
| this.arr = arr; | |||
| this.start = start; | |||
| this.end = end; | |||
| } | |||
| synchronized public void run() { | |||
| arr = mr.radixMulti(arr, start, end); | |||
| done = true; | |||
| notify(); | |||
| } | |||
| synchronized public int[] getSorted() { | |||
| while (!done) { | |||
| try { wait(); } catch (InterruptedException ex) {} | |||
| } | |||
| return arr; | |||
| } | |||
| } | |||
| public int[] sort(int[] arr) { | |||
| MultiRadix mr = new MultiRadix(); | |||
| int n = 4; | |||
| int d = arr.length / n; | |||
| Worker[] workers = new Worker[n]; | |||
| Thread[] threads = new Thread[n]; | |||
| for (int i = 0; i < n; ++i) { | |||
| int start = d * i; | |||
| int end; | |||
| if (i == n - 1) | |||
| end = arr.length; | |||
| else | |||
| end = d * (i + 1); | |||
| Worker w; Thread t; | |||
| workers[i] = w = new Worker(mr, arr, start, end); | |||
| threads[i] = t = new Thread(w); | |||
| t.start(); | |||
| } | |||
| int[][] arrs = new int[n][]; | |||
| for (int i = 0; i < n; ++i) { | |||
| arrs[i] = workers[i].getSorted(); | |||
| try { | |||
| threads[i].join(); | |||
| } catch (InterruptedException ex) {} | |||
| } | |||
| /* | |||
| Worker w = workers[0]; | |||
| int[] a = arrs[0]; | |||
| for (int i = w.start; i < w.end; ++i) { | |||
| System.out.print(a[i]+" "); | |||
| } | |||
| System.out.println(""); | |||
| System.out.println("From "+w.start+" to "+w.end); | |||
| */ | |||
| return arr; | |||
| } | |||
| } | |||
| @@ -0,0 +1,5 @@ | |||
| class Sequential implements Solver { | |||
| public int[] sort(int[] arr) { | |||
| return new MultiRadix().radixMulti(arr); | |||
| } | |||
| } | |||
| @@ -0,0 +1,3 @@ | |||
| interface Solver { | |||
| int[] sort(int[] a); | |||
| } | |||
| @@ -0,0 +1,60 @@ | |||
| import java.util.Arrays; | |||
| class Timer implements Comparable<Timer> { | |||
| public long time = 0; | |||
| private long start = 0; | |||
| Timer() {} | |||
| Timer(long time) { | |||
| this.time = time; | |||
| } | |||
| public Timer start() { | |||
| start = System.nanoTime(); | |||
| return this; | |||
| } | |||
| public Timer end() { | |||
| time = System.nanoTime() - start; | |||
| return this; | |||
| } | |||
| public String prettyTime() { | |||
| if (time < 1000) | |||
| return String.format("%.2fns", time / 1f); | |||
| else if (time < 1000000) | |||
| return String.format("%.2fμs", time / 1000f); | |||
| else if (time < 1000000000) | |||
| return String.format("%.2fms", time / 1000000f); | |||
| else | |||
| return String.format("%.2fs", time / 1000000000f); | |||
| } | |||
| public String prettySpeedup(Timer base) { | |||
| double speedup = (double)base.time / (double)time; | |||
| return String.format("%s (%.2fx speedup)", | |||
| prettyTime(), speedup); | |||
| } | |||
| public static Timer median(Timer[] timers) { | |||
| Arrays.sort(timers); | |||
| Timer med = new Timer(); | |||
| int mid = timers.length / 2; | |||
| if (timers.length % 2 == 0) | |||
| med.time = (timers[mid].time + timers[mid+1].time) / 2; | |||
| else | |||
| med.time = timers[mid].time; | |||
| return med; | |||
| } | |||
| public int compareTo(Timer t) { | |||
| if (this.time < t.time) | |||
| return -1; | |||
| else if (this.time > t.time) | |||
| return 1; | |||
| else | |||
| return 0; | |||
| } | |||
| } | |||