ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/loops/ThreadPhaserJacobi.java
Revision: 1.3
Committed: Fri Oct 30 14:15:04 2009 UTC (14 years, 6 months ago) by dl
Branch: MAIN
Changes since 1.2: +6 -0 lines
Log Message:
Missing file headers

File Contents

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