ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/loops/ThreadPhaserJacobi.java
Revision: 1.9
Committed: Thu Jan 15 18:34:19 2015 UTC (9 years, 3 months ago) by jsr166
Branch: MAIN
CVS Tags: HEAD
Changes since 1.8: +0 -4 lines
Log Message:
delete extraneous blank lines

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/publicdomain/zero/1.0/
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 public void run() {
103 try {
104 double[][] a = A;
105 double[][] b = B;
106
107 for (int i = 0; i < steps; ++i) {
108 maxDiff = update(a, b);
109 if (barrier.awaitAdvance(barrier.arrive()) < 0)
110 break;
111 double[][] tmp = a; a = b; b = tmp;
112 }
113 }
114 catch (Exception ex) {
115 ex.printStackTrace();
116 return;
117 }
118 }
119
120 double update(double[][] a, double[][] b) {
121 double md = 0.0; // local for computing max diff
122
123 for (int i = loRow; i <= hiRow; ++i) {
124 for (int j = loCol; j <= hiCol; ++j) {
125 double v = 0.25 * (a[i-1][j] + a[i][j-1] +
126 a[i+1][j] + a[i][j+1]);
127 b[i][j] = v;
128
129 double diff = v - a[i][j];
130 if (diff < 0) diff = -diff;
131 if (diff > md) md = diff;
132 }
133 }
134
135 return md;
136 }
137
138 }
139
140 static class Driver {
141 double[][] A; // matrix to get old values from
142 double[][] B; // matrix to put new values into
143
144 final int loRow; // indices of current submatrix
145 final int hiRow;
146 final int loCol;
147 final int hiCol;
148 final int steps;
149 Segment[] allSegments;
150
151 Driver(double[][] mat1, double[][] mat2,
152 int firstRow, int lastRow,
153 int firstCol, int lastCol,
154 int steps) {
155
156 this.A = mat1; this.B = mat2;
157 this.loRow = firstRow; this.hiRow = lastRow;
158 this.loCol = firstCol; this.hiCol = lastCol;
159 this.steps = steps;
160
161 int rows = hiRow - loRow + 1;
162 int cols = hiCol - loCol + 1;
163 int rblocks = Math.round((float) rows / dimGran);
164 int cblocks = Math.round((float) cols / dimGran);
165
166 int n = rblocks * cblocks;
167
168 Segment[] segs = new Segment[n];
169 Phaser barrier = new Phaser();
170 int k = 0;
171 for (int i = 0; i < rblocks; ++i) {
172 int lr = loRow + i * dimGran;
173 int hr = lr + dimGran;
174 if (i == rblocks-1) hr = hiRow;
175
176 for (int j = 0; j < cblocks; ++j) {
177 int lc = loCol + j * dimGran;
178 int hc = lc + dimGran;
179 if (j == cblocks-1) hc = hiCol;
180
181 segs[k] = new Segment(A, B, lr, hr, lc, hc, steps, barrier);
182 ++k;
183 }
184 }
185 System.out.println("Using " + n + " segments (threads)");
186 allSegments = segs;
187 }
188
189 public void compute() throws InterruptedException {
190 Segment[] segs = allSegments;
191 int n = segs.length;
192 Thread[] threads = new Thread[n];
193
194 for (int k = 0; k < n; ++k) threads[k] = new Thread(segs[k]);
195 for (int k = 0; k < n; ++k) threads[k].start();
196 for (int k = 0; k < n; ++k) threads[k].join();
197
198 double maxd = 0;
199 for (int k = 0; k < n; ++k) {
200 double md = segs[k].maxDiff;
201 if (md > maxd) maxd = md;
202 }
203
204 System.out.println("Max diff after " + steps + " steps = " + maxd);
205 }
206 }
207 }