ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/loops/ThreadPhaserJacobi.java
Revision: 1.7
Committed: Sat Oct 16 16:22:57 2010 UTC (13 years, 7 months ago) by jsr166
Branch: MAIN
Changes since 1.6: +1 -2 lines
Log Message:
coding style

File Contents

# Content
1 /*
2 * Written by Doug Lea with assistance from members of JCP JSR-166
3 * Expert Group and released to the public domain, as explained at
4 * http://creativecommons.org/licenses/publicdomain
5 */
6
7 // Barrier version of Jacobi iteration
8
9 import java.util.*;
10 import java.util.concurrent.*;
11 //import jsr166y.*;
12
13 public class ThreadPhaserJacobi {
14
15 static final int nprocs = Runtime.getRuntime().availableProcessors();
16
17 /**
18 * The maximum submatrix length (both row-wise and column-wise)
19 * for any Segment
20 */
21 static final double EPSILON = 0.0001; // convergence criterion
22
23 static int dimGran;
24
25 public static void main(String[] args) throws Exception {
26 int n = 2048;
27 int steps = 1000;
28 try {
29 if (args.length > 0)
30 n = Integer.parseInt(args[0]);
31 if (args.length > 1)
32 steps = Integer.parseInt(args[1]);
33 }
34
35 catch (Exception e) {
36 System.out.println("Usage: java ThreadPhaserJacobi <matrix size> <max steps>");
37 return;
38 }
39
40 int granularity = n * n / nprocs;
41 dimGran = (int) Math.sqrt(granularity);
42
43 // allocate enough space for edges
44 int dim = n+2;
45 int ncells = dim * dim;
46 double[][] a = new double[dim][dim];
47 double[][] b = new double[dim][dim];
48 // Initialize interiors to small value
49 double smallVal = 1.0/dim;
50 for (int i = 1; i < dim-1; ++i) {
51 for (int j = 1; j < dim-1; ++j)
52 a[i][j] = smallVal;
53 }
54
55 int nreps = 3;
56 for (int rep = 0; rep < nreps; ++rep) {
57 // Fill all edges with 1's.
58 for (int k = 0; k < dim; ++k) {
59 a[k][0] += 1.0;
60 a[k][n+1] += 1.0;
61 a[0][k] += 1.0;
62 a[n+1][k] += 1.0;
63 }
64 Driver driver = new Driver(a, b, 1, n, 1, n, steps);
65 long startTime = System.currentTimeMillis();
66 driver.compute();
67
68 long time = System.currentTimeMillis() - startTime;
69 double secs = (double) time / 1000.0;
70
71 System.out.println("Compute Time: " + secs);
72 }
73 }
74
75 static class Segment implements Runnable {
76
77 double[][] A; // matrix to get old values from
78 double[][] B; // matrix to put new values into
79
80 // indices of current submatrix
81 final int loRow;
82 final int hiRow;
83 final int loCol;
84 final int hiCol;
85 final int steps;
86 final Phaser barrier;
87 double maxDiff; // maximum difference between old and new values
88
89 Segment(double[][] A, double[][] B,
90 int loRow, int hiRow,
91 int loCol, int hiCol,
92 int steps,
93 Phaser barrier) {
94 this.A = A; this.B = B;
95 this.loRow = loRow; this.hiRow = hiRow;
96 this.loCol = loCol; this.hiCol = hiCol;
97 this.steps = steps;
98 this.barrier = barrier;
99 barrier.register();
100 }
101
102
103 public void run() {
104 try {
105 double[][] a = A;
106 double[][] b = B;
107
108 for (int i = 0; i < steps; ++i) {
109 maxDiff = update(a, b);
110 if (barrier.awaitAdvance(barrier.arrive()) < 0)
111 break;
112 double[][] tmp = a; a = b; b = tmp;
113 }
114 }
115 catch (Exception ex) {
116 ex.printStackTrace();
117 return;
118 }
119 }
120
121 double update(double[][] a, double[][] b) {
122 double md = 0.0; // local for computing max diff
123
124 for (int i = loRow; i <= hiRow; ++i) {
125 for (int j = loCol; j <= hiCol; ++j) {
126 double v = 0.25 * (a[i-1][j] + a[i][j-1] +
127 a[i+1][j] + a[i][j+1]);
128 b[i][j] = v;
129
130 double diff = v - a[i][j];
131 if (diff < 0) diff = -diff;
132 if (diff > md) md = diff;
133 }
134 }
135
136 return md;
137 }
138
139 }
140
141
142 static class Driver {
143 double[][] A; // matrix to get old values from
144 double[][] B; // matrix to put new values into
145
146 final int loRow; // indices of current submatrix
147 final int hiRow;
148 final int loCol;
149 final int hiCol;
150 final int steps;
151 Segment[] allSegments;
152
153 Driver(double[][] mat1, double[][] mat2,
154 int firstRow, int lastRow,
155 int firstCol, int lastCol,
156 int steps) {
157
158 this.A = mat1; this.B = mat2;
159 this.loRow = firstRow; this.hiRow = lastRow;
160 this.loCol = firstCol; this.hiCol = lastCol;
161 this.steps = steps;
162
163 int rows = hiRow - loRow + 1;
164 int cols = hiCol - loCol + 1;
165 int rblocks = Math.round((float) rows / dimGran);
166 int cblocks = Math.round((float) cols / dimGran);
167
168 int n = rblocks * cblocks;
169
170 Segment[] segs = new Segment[n];
171 Phaser barrier = new Phaser();
172 int k = 0;
173 for (int i = 0; i < rblocks; ++i) {
174 int lr = loRow + i * dimGran;
175 int hr = lr + dimGran;
176 if (i == rblocks-1) hr = hiRow;
177
178 for (int j = 0; j < cblocks; ++j) {
179 int lc = loCol + j * dimGran;
180 int hc = lc + dimGran;
181 if (j == cblocks-1) hc = hiCol;
182
183 segs[k] = new Segment(A, B, lr, hr, lc, hc, steps, barrier);
184 ++k;
185 }
186 }
187 System.out.println("Using " + n + " segments (threads)");
188 allSegments = segs;
189 }
190
191 public void compute() throws InterruptedException {
192 Segment[] segs = allSegments;
193 int n = segs.length;
194 Thread[] threads = new Thread[n];
195
196 for (int k = 0; k < n; ++k) threads[k] = new Thread(segs[k]);
197 for (int k = 0; k < n; ++k) threads[k].start();
198 for (int k = 0; k < n; ++k) threads[k].join();
199
200 double maxd = 0;
201 for (int k = 0; k < n; ++k) {
202 double md = segs[k].maxDiff;
203 if (md > maxd) maxd = md;
204 }
205
206 System.out.println("Max diff after " + steps + " steps = " + maxd);
207 }
208 }
209
210
211 }