Added fork-join version of JuliaSetCalculator

This commit is contained in:
Alberto Venturini 2017-09-10 21:18:49 +02:00
parent 74e7095be6
commit 90c10083e9
4 changed files with 166 additions and 75 deletions

View 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;
}
}

View 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;
}
}

View file

@ -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);
}

View file

@ -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(() -> {