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