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; | public interface JuliaSetCalculator { | ||||||
| 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; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
| 
 | 
 | ||||||
|  |     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 width = 1200; | ||||||
|         int height = 800; |         int height = 800; | ||||||
|         JuliaSetCalculator juliaSetCalculator = new JuliaSetCalculator(width, height); |         JuliaSetCalculator juliaSetCalculator = new ForkJoinJuliaSetCalculator(width, height); | ||||||
|         JuliaSetPanel juliaSetPanel = new JuliaSetPanel(juliaSetCalculator, width, height); |         JuliaSetPanel juliaSetPanel = new JuliaSetPanel(juliaSetCalculator, width, height); | ||||||
| 
 | 
 | ||||||
|         SwingUtilities.invokeLater(() -> { |         SwingUtilities.invokeLater(() -> { | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue