130 likes | 235 Views
Computer Science 320. Parallel Image Generation. The Mandelbrot Set. The Mandelbrot Set. A set of points defined as follows: given a point (x, y), compute a sequence of other points (a i , b i ), i = 0, 1, 2, … a 0 = 0 b 0 = 0 a i +1 = a i 2 – b i 2 + x b i +1 = 2 * a i * b i + y
E N D
Computer Science 320 Parallel Image Generation
The Mandelbrot Set A set of points defined as follows: given a point (x, y), compute a sequence of other points (ai, bi), i = 0, 1, 2, … a0 = 0 b0 = 0 ai+1 = ai2 – bi2 + x bi+1 = 2 * ai * bi + y If each point in (ai, bi) stays finite, (x, y) is in; otherwise, not in
The Mandelbrot Set If each point in (ai, bi) stays finite, (x, y) is in; otherwise, not in Can’t do an infinite # of points, so if (ai, bi) ever exceeds a distance of 2 from the origin, it’s not in or: if (ai2 + bi2 )1/2 > 2 for some i
The Mandelbrot Set or: if (ai2 + bi2 )1/2 > 2 for some i If we do 1,000 points, if i reaches this limit before the distance exceeds 2, we’ll call the point in, even if further tests might show it to be out
Program Resources • Will use the Parallel Java Graphics (PJG) format, which is lossless and larger, but uses faster compression, than PNG format • Will generate color values for each point and save these in a PJG file
Program Inputs • Image width and height • Coordinates of the image center point • Image resolution in pixels per unit • Maximum number of iterations to test for membership • Exponent in formula to calculate pixel hues • Output file name
Pixel Matrix, Image File, Hue Table // Create image matrix to store results. matrix = new int [height] [width]; image = new PJGColorImage (height, width, matrix); // Create table of hues for different iteration counts. huetable= new int [maxiter+1]; for (inti = 0; i < maxiter; ++ i){ huetable[i] = HSB.pack(/*hue*/ (float) Math.pow(((double)i) / ((double)maxiter), gamma), /*sat*/ 1.0f, /*bri*/ 1.0f); } huetable[maxiter] = HSB.pack (1.0f, 1.0f, 0.0f);
Optimizing Matrix Access // Compute all rows and columns. for (int r = 0; r < height; ++ r){ int[] matrix_r = matrix[r]; double y = ycenter + (yoffset - r) / resolution; for (int c = 0; c < width; ++ c){ double x = xcenter + (xoffset + c) / resolution; Allows access to a cell with a single index operation
Iterate Until Convergence // Iterate until convergence. int i = 0; double aold = 0.0; double bold = 0.0; double a = 0.0; double b = 0.0; double zmagsqr = 0.0; while (i < maxiter && zmagsqr <= 4.0){ ++ i; a = aold * aold – bold * bold + x; b = 2.0 * aold * bold + y; zmagsqr = a * a + b*b; aold = a; bold = b; } // Record number of iterations for pixel. matrix_r[c] = huetable[i];
Parallelize the Program • Each pixel value can be computed independently, so divide the matrix rows among the threads • All inputs are shared • No per-thread or local variables need synchronization • No padding needed
The Parallel for Loop // Compute all rows and columns. new ParallelTeam().execute(new ParallelRegion(){ public void run() throws Exception{ execute (0, height-1, new IntegerForLoop(){ public void run (int first, int last){ for (int r = first; r <= last; ++ r){ int[] matrix_r = matrix[r]; double y = ycenter + (yoffset - r) / resolution;