Added fork-join version of JuliaSetCalculator
This commit is contained in:
		
							parent
							
								
									74e7095be6
								
							
						
					
					
						commit
						90c10083e9
					
				
					 4 changed files with 166 additions and 75 deletions
				
			
		
							
								
								
									
										81
									
								
								src/ExecutorServiceJuliaSetCalculator.java
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								src/ExecutorServiceJuliaSetCalculator.java
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,81 @@ | |||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| import java.util.concurrent.*; | ||||
| 
 | ||||
| 
 | ||||
| public class ExecutorServiceJuliaSetCalculator implements JuliaSetCalculator { | ||||
|     private int width; | ||||
|     private int height; | ||||
|     private int[][] iterations; | ||||
| 
 | ||||
|     public ExecutorServiceJuliaSetCalculator(final int width, final int height) { | ||||
|         this.width = width; | ||||
|         this.height = height; | ||||
|         iterations = new int[width][height]; | ||||
|     } | ||||
| 
 | ||||
|     public int[][] calculate( | ||||
|             final int maxIterations, | ||||
|             final double zoom, | ||||
|             final double cx, | ||||
|             final double cy, | ||||
|             final double moveX, | ||||
|             final double moveY) { | ||||
| 
 | ||||
|         /** | ||||
|          * Each task calculates one row. I.e. if we have 'width*height' iterations, | ||||
|          * we have 'width' tasks, each of which calculates the value of 'row' iterations. | ||||
|          */ | ||||
|         class JuliaTask implements Runnable { | ||||
| 
 | ||||
|             private int x; | ||||
| 
 | ||||
|             JuliaTask(int x) { | ||||
|                 this.x = x; | ||||
|             } | ||||
| 
 | ||||
|             @Override | ||||
|             public void run() { | ||||
|                 double zx, zy; | ||||
|                 for(int y = 0; y < height; y++) { | ||||
|                     zx = 1.5 * (x - width / 2) / (0.5 * zoom * width) + moveX; | ||||
|                     zy = (y - height / 2) / (0.5 * zoom * height) + moveY; | ||||
|                     int i = maxIterations; | ||||
|                     while (zx * zx + zy * zy < 4 && i > 0) { | ||||
|                         double tmp = zx * zx - zy * zy + cx; | ||||
|                         zy = 2.0 * zx * zy + cy; | ||||
|                         zx = tmp; | ||||
|                         i--; | ||||
|                     } | ||||
|                     iterations[x][y] = i; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         long startTime = System.currentTimeMillis(); | ||||
| 
 | ||||
|         ExecutorService executorService = Executors.newWorkStealingPool(8); | ||||
|         for(int x = 0; x < width; x++) { | ||||
|             JuliaTask task = new JuliaTask(x); | ||||
|             executorService.submit(task); | ||||
|         } | ||||
| 
 | ||||
|         executorService.shutdown(); | ||||
| 
 | ||||
|         try { | ||||
|             executorService.awaitTermination(5, TimeUnit.SECONDS); | ||||
|         } catch (Exception ex) { | ||||
|             System.out.println(ex); | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         long endTime = System.currentTimeMillis(); | ||||
| 
 | ||||
|         System.out.println(endTime - startTime); | ||||
| 
 | ||||
|         return iterations; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
							
								
								
									
										76
									
								
								src/ForkJoinJuliaSetCalculator.java
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								src/ForkJoinJuliaSetCalculator.java
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,76 @@ | |||
| import java.util.concurrent.ForkJoinPool; | ||||
| import java.util.concurrent.RecursiveAction; | ||||
| 
 | ||||
| public class ForkJoinJuliaSetCalculator implements JuliaSetCalculator { | ||||
| 
 | ||||
|     private int width; | ||||
|     private int height; | ||||
|     private int[][] iterations; | ||||
| 
 | ||||
|     public ForkJoinJuliaSetCalculator(final int width, final int height) { | ||||
|         this.width = width; | ||||
|         this.height = height; | ||||
|         iterations = new int[width][height]; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public int[][] calculate(int maxIterations, double zoom, double cx, double cy, double moveX, double moveY) { | ||||
| 
 | ||||
|         class JuliaTask extends RecursiveAction { | ||||
| 
 | ||||
|             private int startInclusive; | ||||
|             private int endExclusive; | ||||
| 
 | ||||
|             private final int THRESHOLD = 10; | ||||
| 
 | ||||
|             JuliaTask(int startInclusive, int endExclusive) { | ||||
|                 this.startInclusive = startInclusive; | ||||
|                 this.endExclusive = endExclusive; | ||||
|             } | ||||
| 
 | ||||
|             private void computeDirectly() { | ||||
|                 double zx, zy; | ||||
| 
 | ||||
|                 for(int x = startInclusive; x < endExclusive; x++) { | ||||
|                     for (int y = 0; y < height; y++) { | ||||
|                         zx = 1.5 * (x - width / 2) / (0.5 * zoom * width) + moveX; | ||||
|                         zy = (y - height / 2) / (0.5 * zoom * height) + moveY; | ||||
|                         int i = maxIterations; | ||||
|                         while (zx * zx + zy * zy < 4 && i > 0) { | ||||
|                             double tmp = zx * zx - zy * zy + cx; | ||||
|                             zy = 2.0 * zx * zy + cy; | ||||
|                             zx = tmp; | ||||
|                             i--; | ||||
|                         } | ||||
|                         iterations[x][y] = i; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             @Override | ||||
|             protected void compute() { | ||||
|                 if(endExclusive - startInclusive < THRESHOLD) { | ||||
|                     computeDirectly(); | ||||
|                 } else { | ||||
|                     int middle = (startInclusive + endExclusive) / 2; | ||||
|                     JuliaTask task1 = new JuliaTask(startInclusive, middle); | ||||
|                     JuliaTask task2 = new JuliaTask(middle, endExclusive); | ||||
|                     invokeAll(task1, task2); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         long startTime = System.currentTimeMillis(); | ||||
| 
 | ||||
|         JuliaTask task = new JuliaTask(0, width); | ||||
|         System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism", Integer.toString(8)); | ||||
|         ForkJoinPool.commonPool().invoke(task); | ||||
| 
 | ||||
|         long endTime = System.currentTimeMillis(); | ||||
|         System.out.println(endTime - startTime); | ||||
| 
 | ||||
|         return iterations; | ||||
|          | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  | @ -1,77 +1,11 @@ | |||
| import java.util.concurrent.ExecutorService; | ||||
| import java.util.concurrent.Executors; | ||||
| import java.util.concurrent.TimeUnit; | ||||
| 
 | ||||
| 
 | ||||
| public class JuliaSetCalculator { | ||||
|     private int width; | ||||
|     private int height; | ||||
|     private int[][] iterations; | ||||
| 
 | ||||
|     public JuliaSetCalculator(final int width, final int height) { | ||||
|         this.width = width; | ||||
|         this.height = height; | ||||
|         iterations = new int[width][height]; | ||||
|     } | ||||
| 
 | ||||
|     public int[][] calculate( | ||||
|             final int maxIterations, | ||||
|             final double zoom, | ||||
|             final double cx, | ||||
|             final double cy, | ||||
|             final double moveX, | ||||
|             final double moveY) { | ||||
| 
 | ||||
|         class JuliaTask implements Runnable { | ||||
| 
 | ||||
|             private int x; | ||||
| 
 | ||||
|             JuliaTask(int x) { | ||||
|                 this.x = x; | ||||
|             } | ||||
| 
 | ||||
|             @Override | ||||
|             public void run() { | ||||
|                 double zx, zy; | ||||
|                 for(int y = 0; y < height; y++) { | ||||
|                     zx = 1.5 * (x - width / 2) / (0.5 * zoom * width) + moveX; | ||||
|                     zy = (y - height / 2) / (0.5 * zoom * height) + moveY; | ||||
|                     int i = maxIterations; | ||||
|                     while (zx * zx + zy * zy < 4 && i > 0) { | ||||
|                         double tmp = zx * zx - zy * zy + cx; | ||||
|                         zy = 2.0 * zx * zy + cy; | ||||
|                         zx = tmp; | ||||
|                         i--; | ||||
|                     } | ||||
|                     iterations[x][y] = i; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         long startTime = System.currentTimeMillis(); | ||||
| 
 | ||||
|         ExecutorService executorService = Executors.newWorkStealingPool(8); | ||||
|         for(int x = 0; x < width; x++) { | ||||
|             JuliaTask task = new JuliaTask(x); | ||||
|             executorService.submit(task); | ||||
|         } | ||||
| 
 | ||||
|         executorService.shutdown(); | ||||
| 
 | ||||
|         try { | ||||
|             executorService.awaitTermination(5, TimeUnit.SECONDS); | ||||
|         } catch (Exception ex) { | ||||
|             System.out.println(ex); | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         long endTime = System.currentTimeMillis(); | ||||
| 
 | ||||
|         System.out.println(endTime - startTime); | ||||
| 
 | ||||
|         return iterations; | ||||
|     } | ||||
| 
 | ||||
| public interface JuliaSetCalculator { | ||||
| 
 | ||||
|     int[][] calculate( | ||||
|             int maxIterations, | ||||
|             double zoom, | ||||
|             double cx, | ||||
|             double cy, | ||||
|             double moveX, | ||||
|             double moveY); | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -7,7 +7,7 @@ public class MainClass { | |||
| 
 | ||||
|         int width = 1200; | ||||
|         int height = 800; | ||||
|         JuliaSetCalculator juliaSetCalculator = new JuliaSetCalculator(width, height); | ||||
|         JuliaSetCalculator juliaSetCalculator = new ForkJoinJuliaSetCalculator(width, height); | ||||
|         JuliaSetPanel juliaSetPanel = new JuliaSetPanel(juliaSetCalculator, width, height); | ||||
| 
 | ||||
|         SwingUtilities.invokeLater(() -> { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue