18 |
|
if (args.length > 1) |
19 |
|
steps = Integer.parseInt(args[1]); |
20 |
|
} |
21 |
< |
|
21 |
> |
|
22 |
|
catch (Exception e) { |
23 |
|
System.out.println("Usage: java ThreadPhaserJacobi <matrix size> <max steps>"); |
24 |
|
return; |
25 |
|
} |
26 |
< |
|
26 |
> |
|
27 |
|
ForkJoinPool fjp = new ForkJoinPool(); |
28 |
|
int granularity = n * n / fjp.getParallelism(); |
29 |
|
dimGran = (int)(Math.sqrt(granularity)); |
30 |
< |
|
30 |
> |
|
31 |
|
// allocate enough space for edges |
32 |
|
int dim = n+2; |
33 |
|
int ncells = dim * dim; |
34 |
|
double[][] a = new double[dim][dim]; |
35 |
|
double[][] b = new double[dim][dim]; |
36 |
|
// Initialize interiors to small value |
37 |
< |
double smallVal = 1.0/dim; |
37 |
> |
double smallVal = 1.0/dim; |
38 |
|
for (int i = 1; i < dim-1; ++i) { |
39 |
|
for (int j = 1; j < dim-1; ++j) |
40 |
|
a[i][j] = smallVal; |
51 |
|
Driver driver = new Driver(a, b, 1, n, 1, n, steps); |
52 |
|
long startTime = System.currentTimeMillis(); |
53 |
|
fjp.invoke(driver); |
54 |
< |
|
54 |
> |
|
55 |
|
long time = System.currentTimeMillis() - startTime; |
56 |
|
double secs = ((double)time) / 1000.0; |
57 |
< |
|
57 |
> |
|
58 |
|
System.out.println("Compute Time: " + secs); |
59 |
|
System.out.println(fjp); |
60 |
|
|
61 |
|
} |
62 |
< |
|
62 |
> |
|
63 |
|
} |
64 |
|
|
65 |
|
static class Segment extends CyclicAction { |
66 |
|
double[][] A; // matrix to get old values from |
67 |
|
double[][] B; // matrix to put new values into |
68 |
|
// indices of current submatrix |
69 |
< |
final int loRow; |
69 |
> |
final int loRow; |
70 |
|
final int hiRow; |
71 |
|
final int loCol; |
72 |
|
final int hiCol; |
73 |
|
volatile double maxDiff; // maximum difference between old and new values |
74 |
|
|
75 |
< |
Segment(double[][] A, double[][] B, |
75 |
> |
Segment(double[][] A, double[][] B, |
76 |
|
int loRow, int hiRow, |
77 |
< |
int loCol, int hiCol, |
77 |
> |
int loCol, int hiCol, |
78 |
|
Phaser br) { |
79 |
|
super(br); |
80 |
|
this.A = A; this.B = B; |
104 |
|
|
105 |
|
return md; |
106 |
|
} |
107 |
< |
|
107 |
> |
|
108 |
|
} |
109 |
|
|
110 |
|
static class MyPhaser extends Phaser { |
115 |
|
} |
116 |
|
} |
117 |
|
|
118 |
< |
static class Driver extends RecursiveAction { |
118 |
> |
static class Driver extends RecursiveAction { |
119 |
|
double[][] A; // matrix to get old values from |
120 |
|
double[][] B; // matrix to put new values into |
121 |
|
final int loRow; // indices of current submatrix |
123 |
|
final int loCol; |
124 |
|
final int hiCol; |
125 |
|
final int steps; |
126 |
< |
Driver(double[][] mat1, double[][] mat2, |
126 |
> |
Driver(double[][] mat1, double[][] mat2, |
127 |
|
int firstRow, int lastRow, |
128 |
|
int firstCol, int lastCol, |
129 |
|
int steps) { |
130 |
< |
|
130 |
> |
|
131 |
|
this.A = mat1; this.B = mat2; |
132 |
|
this.loRow = firstRow; this.hiRow = lastRow; |
133 |
|
this.loCol = firstCol; this.hiCol = lastCol; |
139 |
|
int cols = hiCol - loCol + 1; |
140 |
|
int rblocks = (int)(Math.round((float)rows / dimGran)); |
141 |
|
int cblocks = (int)(Math.round((float)cols / dimGran)); |
142 |
< |
|
142 |
> |
|
143 |
|
int n = rblocks * cblocks; |
144 |
< |
|
144 |
> |
|
145 |
|
System.out.println("Using " + n + " segments"); |
146 |
< |
|
146 |
> |
|
147 |
|
Segment[] segs = new Segment[n]; |
148 |
|
Phaser barrier = new MyPhaser(steps); |
149 |
|
int k = 0; |
151 |
|
int lr = loRow + i * dimGran; |
152 |
|
int hr = lr + dimGran; |
153 |
|
if (i == rblocks-1) hr = hiRow; |
154 |
< |
|
154 |
> |
|
155 |
|
for (int j = 0; j < cblocks; ++j) { |
156 |
|
int lc = loCol + j * dimGran; |
157 |
|
int hc = lc + dimGran; |
158 |
|
if (j == cblocks-1) hc = hiCol; |
159 |
< |
|
159 |
> |
|
160 |
|
segs[k] = new Segment(A, B, lr, hr, lc, hc, barrier); |
161 |
|
++k; |
162 |
|
} |
171 |
|
} |
172 |
|
} |
173 |
|
} |
174 |
– |
|