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