Browse Source

done.

master
mortie 7 years ago
parent
commit
3cd3e724a5

+ 3
- 3
inf2440/hw3/Main.java View File

@@ -3,8 +3,8 @@ import java.util.Random;
class Main {
public static void main(String[] args) {

Solver sseq = new Sequential();
Solver spar = new Parallel();
Sorter sseq = new MultiRadix();
Sorter spar = new MultiRadixPar();

if (args.length != 1) {
System.out.println(" bruk : >java SekvensiellRadix <n> ");
@@ -18,7 +18,7 @@ class Main {
}
}

static Timer test (Solver s, int len) {
static Timer test (Sorter s, int len) {
Random r = new Random(123);

int[] a = new int[len];

+ 5
- 10
inf2440/hw3/MultiRadix.java View File

@@ -5,11 +5,15 @@ import java.util.*;
* for store verdier av n > 100 m, kjør (f.eks):
* >java -Xmx16000m MultiRadix 1000000000
************************************************************/
class MultiRadix{
class MultiRadix implements Sorter {
int n;
int [] a;
final static int NUM_BIT = 7; // alle tall 6-11 .. finn ut hvilken verdi som er best
public int[] sort(int[] arr) {
return radixMulti(arr);
}
int [] radixMulti(int [] a) {
long tt = System.nanoTime();
// 1-5 digit radixSort of : a[]
@@ -17,11 +21,9 @@ class MultiRadix{
int [] bit ;
// a) finn max verdi i a[]
Timer ta = new Timer().start();
for (int i = 1 ; i < n ; i++)
if (a[i] > max) max = a[i];
while (max >= (1L<<numBit) )numBit++; // antall binaere siffer i max
System.out.println("A: "+ta.end().prettyTime());
// bestem antall bit i numBits sifre
numDigits = Math.max(1, numBit/NUM_BIT);
@@ -59,28 +61,21 @@ class MultiRadix{
int [] count = new int [mask+1];
// b) count=the frequency of each radix value in a
//Timer tb = new Timer().start();
for (int i = 0; i < n; i++) {
count[(a[i]>>> shift) & mask]++;
}
//System.out.println("B: "+tb.end().prettyTime());
// c) Add up in 'count' - accumulated values
//Timer tc = new Timer().start();
for (int i = 0; i <= mask; i++) {
j = count[i];
count[i] = acumVal;
acumVal += j;
}
//System.out.println("C: "+tc.end().prettyTime());
// d) move numbers in sorted order a to b
Timer t = new Timer().start();
for (int i = 0; i < n; i++) {
b[count[(a[i]>>>shift) & mask]++] = a[i];
}
t.end();
System.out.println("seq D: "+t.prettyTime());
}// end radixSort

+ 126
- 62
inf2440/hw3/MultiRadixPar.java View File

@@ -1,19 +1,31 @@
import java.util.*;
class MultiRadixPar{
import java.util.concurrent.CyclicBarrier;
/***********************************************************
* Oblig 3 - sekvensiell kode, INF2440 v2017.
* Ifi, Uio, Arne Maus
* for store verdier av n > 100 m, kjør (f.eks):
* >java -Xmx16000m MultiRadix 1000000000
************************************************************/
class MultiRadixPar implements Sorter {
int n;
volatile int[] a;
int [] a;
final static int NUM_BIT = 7; // alle tall 6-11 .. finn ut hvilken verdi som er best
int nThreads = Math.min(
Runtime.getRuntime().availableProcessors(),
8);
16);
public int[] sort(int[] arr) {
return radixMulti(arr);
}
class PartAWorker implements Runnable {
int[] a;
int start;
int end;
int biggest;
PartAWorker(int start, int end) {
PartAWorker(int[] a, int start, int end) {
this.a = a;
this.start = start;
this.end = end;
this.biggest = a[start];
@@ -27,33 +39,30 @@ class MultiRadixPar{
}
}
int [] radixMulti(int [] a_) {
this.a = a_;
nThreads = 2;
int [] radixMulti(int [] a) {
long tt = System.nanoTime();
// 1-5 digit radixSort of : a[]
int max = a[0], numBit = 2, numDigits, n =a.length;
int [] bit ;
// a) finn max verdi i a[]
Timer ta = new Timer().start();
int d = a.length / nThreads;
Thread[] threads = new Thread[nThreads];
PartAWorker[] workers = new PartAWorker[nThreads];
for (int i = 0; i < nThreads; ++i) {
PartAWorker w = workers[i] = new PartAWorker(
d * i, i == nThreads - 1 ? a.length : d * (i + 1));
a, d * i, i == nThreads - 1 ? a.length : d * (i + 1));
Thread t = threads[i] = new Thread(w);
t.start();
}
for (int i = 0; i < nThreads; ++i) {
try { threads[i].join(); } catch (InterruptedException ex) {}
for (Thread t: threads) { try { t.join(); } catch (InterruptedException ex) {} }
max = workers[0].biggest;
for (int i = 1; i < nThreads; ++i) {
if (workers[i].biggest > max)
max = workers[i].biggest;
}
while (max >= (1L<<numBit) )numBit++; // antall binaere siffer i max
System.out.println("A: "+ta.end().prettyTime());
// bestem antall bit i numBits sifre
numDigits = Math.max(1, numBit/NUM_BIT);
@@ -69,89 +78,144 @@ class MultiRadixPar{
int[] t=a, b = new int [n];
for (int i =0; i < bit.length; i++) {
radixSort( b,bit[i],sum ); // i-te siffer fra a[] til b[]
radixSort( a,b,bit[i],sum ); // i-te siffer fra a[] til b[]
sum += bit[i];
// swap arrays (pointers only)
t = a;
a = b;
b = t;
}
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);
}
return a;
} // end radixMulti
class PartDWorker implements Runnable {
int start, end, shift, mask;
int[] b, count;
PartDWorker(int start, int end, int[] b, int[] count, int shift, int mask) {
this.start = start;
this.end = end;
class Worker extends Thread {
int index;
CyclicBarrier barrier;
int[] a;
int[] b;
int[][] accumulated;
int[] globalCount;
int[][] count2d;
int mask;
int shift;
int start;
int end;
boolean doD = false;
int acumVal;
int j;
int[] count;
Worker(
int index, CyclicBarrier barrier,
int[] a, int[] b, int[][] accumulated,
int[] globalCount, int[][] count2d,
int mask, int shift,
int start, int end) {
this.index = index;
this.barrier = barrier;
this.a = a;
this.b = b;
this.count = new int[mask + 1];
this.shift = shift;
this.accumulated = accumulated;
this.globalCount = globalCount;
this.count2d = count2d;
this.mask = mask;
}
this.shift = shift;
this.start = start;
this.end = end;
public void run() {
acumVal = 0;
j = 0;
count = new int[mask+1];
}
/*
synchronized public void run() {
// b) count=the frequency of each radix value in a
//Timer tb = new Timer().start();
for (int i = 0; i < n; i++) {
int var = (a[i]>>>shift) & mask;
count[var]++;
if (var > biggestVar)
biggestVar = var;
for (int i = start; i < end; i++) {
count[(a[i]>>> shift) & mask]++;
}
//System.out.println("B: "+tb.end().prettyTime());
// c) Add up in 'count' - accumulated values
Timer tc = new Timer().start();
int j = 0;
int acumVal = 0;
for (int i = 0; i <= mask; i++) {
count2d[index][i] = count[i];
j = count[i];
count[i] = acumVal;
accumulated[index][i] = acumVal;
acumVal += j;
}
System.out.println("C: "+tc.end().prettyTime());
// d)
for (int i = 0; i < n; i++) {
int var = (a[i] >>> shift) & mask;
if (var >= start && var < end) {
b[count[var]++] = a[i];
// Wait for synchronization
try { barrier.await(); } catch (Exception ex) {}
while (!doD)
try { wait(); } catch (InterruptedException ex) {}
// d) move numbers in sorted order a to b
int[] space = new int[mask + 1];
for (int i = 0; i < mask + 1; ++i) {
for (int j = 0; j < index; ++j) {
space[i] += count2d[j][i];
}
}
*/
for (int i = start; i < end; i++) {
int idx = (a[i] >>> shift) & mask;
b[globalCount[idx] + space[idx]++] = a[i];
}
}
synchronized public void startPartD() {
this.doD = true;
notify();
}
}
/** Sort a[] on one digit ; number of bits = maskLen, shiftet up 'shift' bits */
void radixSort (int [] b, int maskLen, int shift){
int n = a.length;
int mask = (1<<maskLen) -1;
int [] count = new int [mask+1];
/*
Timer td = new Timer().start();
int d = biggestVar / nThreads;
Thread[] threads = new Thread[nThreads];
void radixSort ( int [] a, int [] b, int maskLen, int shift){
int mask = (1 << maskLen) - 1;
CyclicBarrier barrier = new CyclicBarrier(nThreads + 1);
int[][] accumulated = new int[nThreads][mask + 1];
int[][] count2d = new int[nThreads][mask + 1];
int[] count = new int[mask + 1];
// Create and start workers
Worker[] workers = new Worker[nThreads];
int d = a.length / nThreads;
for (int i = 0; i < nThreads; ++i) {
int start = d * i;
int end = i == nThreads - 1 ? n + 1 : d * (i + 1);
int end = i == nThreads - 1 ? a.length : d * (i + 1);
workers[i] = new Worker(
i, barrier,
a, b, accumulated,
count, count2d,
mask, shift,
start, end);
workers[i].start();
}
PartDWorker w = new PartDWorker(start, end, b, count, shift, mask);
Thread t = threads[i] = new Thread(w);
t.start();
// Synchronize
try { barrier.await(); } catch (Exception ex) {}
// Sequentially fix count
for (int i=0; i < count.length; ++i) {
for (int j = 0; j < nThreads; ++j) {
count[i] += accumulated[j][i];
}
}
// Do part D
for (Worker w: workers) {
w.startPartD();
}
for (Thread t: threads) {
try { t.join(); } catch (InterruptedException ex) {}
// Join threads
for (int i = 0; i < nThreads; ++i) {
try { workers[i].join(); } catch (InterruptedException ex) {}
}
System.out.println("par D: "+td.end().prettyTime());
*/
}// end radixSort
void testSort(int [] a){

+ 0
- 5
inf2440/hw3/Parallel.java View File

@@ -1,5 +0,0 @@
class Parallel implements Solver {
public int[] sort(int[] arr) {
return new MultiRadixPar().radixMulti(arr);
}
}

+ 0
- 5
inf2440/hw3/Sequential.java View File

@@ -1,5 +0,0 @@
class Sequential implements Solver {
public int[] sort(int[] arr) {
return new MultiRadix().radixMulti(arr);
}
}

+ 0
- 3
inf2440/hw3/Solver.java View File

@@ -1,3 +0,0 @@
interface Solver {
int[] sort(int[] a);
}

+ 3
- 0
inf2440/hw3/Sorter.java View File

@@ -0,0 +1,3 @@
interface Sorter {
public int[] sort(int[] arr);
}

+ 3
- 0
inf2440/hw3/output.txt View File

@@ -0,0 +1,3 @@
martin@elli:~/tmp$ java Main 200000000
Sequential: 5.01s
Parallel: 1.72s (2.92x speedup)

+ 45
- 0
inf2440/hw3/rapport.txt View File

@@ -0,0 +1,45 @@
Kompilering: `javac *.java`
Kjøring: `java Main <tall>`

# Eksempelutskrift

I filen output.txt finner du et eksempel på å kjøre `java Main 200000000`.

# Tider

CPU: quad core Intel Xeon E31225 @ 3.1 GHz (ingen hyperthreading)

200 000 000:
* Sekvensiell: 5.02s
* Parallell: 1.73s (2.90x speedup)

20 000 000:
* Sekvensiell: 274.08ms
* Parallell: 147.10ms (1.86x speedup)

2 000 000:
* Sekvensiell: 56.23ms
* Parallell: 72.32ms (0.78x speedup)

200 000:
* Sekvensiell: 23.59ms
* Parallell: 23.28ms (1.01x speedup)

20 000:
* Sekvensiell: 3.20ms
* Parallell: 6.63ms (0.48x speedup)

2 000:
* Sekvensiell: 270.98μs
* Parallell: 5.00ms (0.05x speedup)

## Del C

Jeg har et 2D-array kalt count2d. Tråd 0 skriver til count2d[0], 1 skriver til
count2d[1], etc. Dette gjør samme algoritme som den sekvensielle del C, men
bruker et count-array laget av del B med kun den delen av arrayet som
tråden er ansvarlig for. Den ferdige akkumulerte verdien ender opp i et annet
2D-array som heter accumulated. Når alle trådene er ferdig med dette,
går main-tråden igjennom alle arrayene i accumulated-arrayet, og samler
verdiene i et count-array (som inni trådene heter globalCount).
Etter at det er ferdig er vi klare til å sette igang del D i alle trådene.

Loading…
Cancel
Save