1 3 import EDU.oswego.cs.dl.util.concurrent.*; 4 5 public class BarrierJacobi { 6 7 static final int DEFAULT_GRANULARITY = 128; 8 9 13 14 static int granularity = DEFAULT_GRANULARITY; 15 16 static final double EPSILON = 0.001; 18 19 public static void main(String [] args) { 20 try { 21 int n; 22 int steps; 23 try { 24 n = Integer.parseInt(args[0]); 25 steps = Integer.parseInt(args[1]); 26 if (args.length > 2) granularity = Integer.parseInt(args[2]); 27 } 28 29 catch (Exception e) { 30 System.out.println("Usage: java BarrierJacobi <matrix size> <max steps> [<granularity>]"); 31 return; 32 } 33 34 36 double[][] a = new double[n+2][n+2]; 37 double[][] b = new double[n+2][n+2]; 38 39 40 43 for (int k = 0; k < n+2; ++k) { 44 a[k][0] = 1.0; 45 a[k][n+1] = 1.0; 46 a[0][k] = 1.0; 47 a[n+1][k] = 1.0; 48 49 b[k][0] = 1.0; 50 b[k][n+1] = 1.0; 51 b[0][k] = 1.0; 52 b[n+1][k] = 1.0; 53 } 54 55 long startTime = System.currentTimeMillis(); 56 57 new Driver(a, b, 1, n, 1, n, steps).compute(); 58 59 long time = System.currentTimeMillis() - startTime; 60 double secs = ((double)time) / 1000.0; 61 62 System.out.println("Compute Time: " + secs); 63 64 } 65 catch (InterruptedException ex) {} 66 } 67 68 static class Segment implements Runnable { 69 70 double[][] A; double[][] B; 73 final int loRow; 75 final int hiRow; 76 final int loCol; 77 final int hiCol; 78 final int steps; 79 final CyclicBarrier barrier; 80 81 final Segment[] allSegments; 82 83 volatile double maxDiff; volatile boolean converged = false; 85 86 Segment(double[][] A, double[][] B, 87 int loRow, int hiRow, 88 int loCol, int hiCol, 89 int steps, 90 CyclicBarrier barrier, 91 Segment[] allSegments) { 92 this.A = A; this.B = B; 93 this.loRow = loRow; this.hiRow = hiRow; 94 this.loCol = loCol; this.hiCol = hiCol; 95 this.steps = steps; 96 this.barrier = barrier; 97 this.allSegments = allSegments; 98 } 99 100 void convergenceCheck(int step) { 101 for (int i = 0; i < allSegments.length; ++i) 102 if (allSegments[i].maxDiff > EPSILON) return; 103 104 System.out.println("Converged after " + step + " steps"); 105 106 for (int i = 0; i < allSegments.length; ++i) 107 allSegments[i].converged = true; 108 } 109 110 111 public void run() { 112 try { 113 double[][] a = A; 114 double[][] b = B; 115 116 for (int i = 1; i <= steps && !converged; ++i) { 117 maxDiff = update(a, b); 118 119 int index = barrier.barrier(); 120 if (index == 0) convergenceCheck(i); 121 barrier.barrier(); 122 123 double[][] tmp = a; a = b; b = tmp; 124 } 125 } 126 catch(Exception ex) { 127 return; 128 } 129 } 130 131 double update(double[][] a, double[][] b) { 132 double md = 0.0; 134 for (int i = loRow; i <= hiRow; ++i) { 135 for (int j = loCol; j <= hiCol; ++j) { 136 double v = 0.25 * (a[i-1][j] + a[i][j-1] + 137 a[i+1][j] + a[i][j+1]); 138 b[i][j] = v; 139 140 double diff = v - a[i][j]; 141 if (diff < 0) diff = -diff; 142 if (diff > md) md = diff; 143 } 144 } 145 146 return md; 147 } 148 149 } 150 151 152 static class Driver { 153 double[][] A; double[][] B; 156 final int loRow; final int hiRow; 158 final int loCol; 159 final int hiCol; 160 final int steps; 161 162 Driver(double[][] mat1, double[][] mat2, 163 int firstRow, int lastRow, 164 int firstCol, int lastCol, 165 int steps) { 166 167 this.A = mat1; this.B = mat2; 168 this.loRow = firstRow; this.hiRow = lastRow; 169 this.loCol = firstCol; this.hiCol = lastCol; 170 this.steps = steps; 171 } 172 173 public void compute() throws InterruptedException { 174 175 int rows = hiRow - loRow + 1; 176 int cols = hiCol - loCol + 1; 177 int rblocks = rows / granularity; 178 int cblocks = cols / granularity; 179 180 int n = rblocks * cblocks; 181 182 System.out.println("Using " + n + " segments (threads)"); 183 184 Segment[] segs = new Segment[n]; 185 Thread [] threads = new Thread [n]; 186 CyclicBarrier barrier = new CyclicBarrier(n); 187 188 int k = 0; 189 for (int i = 0; i < rblocks; ++i) { 190 int lr = loRow + i * granularity; 191 int hr = lr + granularity; 192 if (i == rblocks-1) hr = hiRow; 193 194 for (int j = 0; j < cblocks; ++j) { 195 int lc = loCol + j * granularity; 196 int hc = lc + granularity; 197 if (j == cblocks-1) hc = hiCol; 198 199 segs[k] = new Segment(A, B, lr, hr, lc, hc, steps, barrier, segs); 200 threads[k] = new Thread (segs[k]); 201 ++k; 202 } 203 } 204 205 for (k = 0; k < n; ++k) threads[k].start(); 206 207 for (k = 0; k < n; ++k) threads[k].join(); 208 209 double maxd = 0; 210 for (k = 0; k < n; ++k) { 211 double md = segs[k].maxDiff; 212 if (md > maxd) maxd = md; 213 } 214 215 System.out.println("Max diff after " + steps + " steps = " + maxd); 216 217 218 } 219 } 220 221 222 } 223 | Popular Tags |