forked from Parallele_Programmierung/Labs
Kap. 12: Fork-Join
parent
3bf39b1f4c
commit
5aa83f1b3d
|
|
@ -0,0 +1,7 @@
|
||||||
|
# Laboraufgabe "in-situ Filterung als divide and conquer"
|
||||||
|
- [Aufgabenstellung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/12-01-ForkJoinArrayFilter.html)
|
||||||
|
- [Musterlösung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/12-Solutions.html#laboraufgabe-in-situ-filterung-als-divide-and-conquer)
|
||||||
|
|
||||||
|
# Materialien
|
||||||
|
- [Folien](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/slides/12-forkjoin.html)
|
||||||
|
- [Skript](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/notes/12-forkjoin.html)
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
# Justfile (https://just.systems/) for starting Maven standard targets
|
||||||
|
|
||||||
|
default:
|
||||||
|
just exec pp.FilterTask ""
|
||||||
|
|
||||||
|
exec class args: compile
|
||||||
|
mvn exec:java -Dexec.args="{{args}}" -Dexec.mainClass={{class}}
|
||||||
|
# exec class args:
|
||||||
|
# java -cp target/app.jar {{class}} {{args}}
|
||||||
|
clean:
|
||||||
|
mvn clean
|
||||||
|
compile:
|
||||||
|
mvn compile
|
||||||
|
test: compile
|
||||||
|
mvn test
|
||||||
|
javadoc:
|
||||||
|
mvn javadoc:javadoc
|
||||||
|
package:
|
||||||
|
mvn package
|
||||||
|
|
@ -0,0 +1,72 @@
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>pp</groupId>
|
||||||
|
<artifactId>pp.12.01-ForkJoinArrayFilter</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<exec.mainClass>pp.FilterTask</exec.mainClass>
|
||||||
|
<maven.compiler.release>10</maven.compiler.release>
|
||||||
|
<lombok.version>edge-SNAPSHOT</lombok.version>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
<dependencies>
|
||||||
|
<dependency><!-- für Unit-Tests -->
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter</artifactId>
|
||||||
|
<version>5.10.0</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency><!-- für Lombok -->
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>${lombok.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency><!-- für net.jcip Annotationen -->
|
||||||
|
<groupId>net.jcip</groupId>
|
||||||
|
<artifactId>jcip-annotations</artifactId>
|
||||||
|
<version>1.0</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<build>
|
||||||
|
<defaultGoal>clean compile exec:java</defaultGoal>
|
||||||
|
<plugins>
|
||||||
|
<plugin><!-- für Unit-Tests [mvn test] -->
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<version>3.0.0</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin><!-- [mvn compile] -->
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.9.0</version>
|
||||||
|
<configuration>
|
||||||
|
<annotationProcessorPaths>
|
||||||
|
<path>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>${lombok.version}</version>
|
||||||
|
</path>
|
||||||
|
</annotationProcessorPaths>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin><!-- [mvn exec:java] -->
|
||||||
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
|
<artifactId>exec-maven-plugin</artifactId>
|
||||||
|
<version>3.1.0</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin><!-- [mvn javadoc:javadoc] -->
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
|
<version>3.5.0</version>
|
||||||
|
<configuration>
|
||||||
|
<show>private</show>
|
||||||
|
<locale>en_US</locale>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
package pp;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.concurrent.RecursiveAction;
|
||||||
|
import java.util.concurrent.ForkJoinPool;
|
||||||
|
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
public class FilterTask extends RecursiveAction {
|
||||||
|
|
||||||
|
private static final int ARRAY_LEN = 16;
|
||||||
|
private static final int SLICE_LEN = 4;
|
||||||
|
private static final int MAX = 10;
|
||||||
|
private static int instanceCounter = 0;
|
||||||
|
|
||||||
|
private final ArrayList<Integer> array;
|
||||||
|
private final int start;
|
||||||
|
private final int end;
|
||||||
|
|
||||||
|
FilterTask(ArrayList<Integer> array, int start, int end) {
|
||||||
|
this.array = array;
|
||||||
|
this.start = start;
|
||||||
|
this.end = end;
|
||||||
|
synchronized(FilterTask.class) {
|
||||||
|
FilterTask.instanceCounter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void compute() {
|
||||||
|
|
||||||
|
// Fallunterscheidung einführen, die prüft, ob weiter rekursiv halbiert
|
||||||
|
// werden muss oder ob nun der Rekursionsanker erreicht ist
|
||||||
|
|
||||||
|
// Rekursionsanker: über Array-Elemente mit einer for-Schleife iterieren
|
||||||
|
// und Filter-Aktion anwenden (muss noch implementiert werden)
|
||||||
|
|
||||||
|
// Array in zwei Hälften aufteilen und beide Hälften rekursiv behandeln:
|
||||||
|
var mid = this.start + ((this.end - this.start) / 2);
|
||||||
|
var left = new FilterTask(this.array, this.start, mid);
|
||||||
|
var right = new FilterTask(this.array, mid, this.end);
|
||||||
|
left.fork();
|
||||||
|
right.fork();
|
||||||
|
right.join();
|
||||||
|
left.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String... args) {
|
||||||
|
// Array initialisieren
|
||||||
|
|
||||||
|
// initialen FilterTask erzeugen und
|
||||||
|
// FilterTask im *Common Thread Pool* starten:
|
||||||
|
// ForkJoinPool.commonPool().invoke(...);
|
||||||
|
|
||||||
|
// auf das Ende warten
|
||||||
|
// gefiltertes Array ausgeben
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
# Laboraufgabe "in-situ Filterung als divide and conquer"
|
||||||
|
- [Aufgabenstellung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/12-01-ForkJoinArrayFilter.html)
|
||||||
|
- [Musterlösung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/12-Solutions.html#laboraufgabe-in-situ-filterung-als-divide-and-conquer)
|
||||||
|
|
||||||
|
# Materialien
|
||||||
|
- [Folien](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/slides/12-forkjoin.html)
|
||||||
|
- [Skript](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/notes/12-forkjoin.html)
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
# Justfile (https://just.systems/) for starting Maven standard targets
|
||||||
|
|
||||||
|
default:
|
||||||
|
just exec pp.FilterTask ""
|
||||||
|
|
||||||
|
exec class args: compile
|
||||||
|
mvn exec:java -Dexec.args="{{args}}" -Dexec.mainClass={{class}}
|
||||||
|
# exec class args:
|
||||||
|
# java -cp target/app.jar {{class}} {{args}}
|
||||||
|
clean:
|
||||||
|
mvn clean
|
||||||
|
compile:
|
||||||
|
mvn compile
|
||||||
|
test: compile
|
||||||
|
mvn test
|
||||||
|
javadoc:
|
||||||
|
mvn javadoc:javadoc
|
||||||
|
package:
|
||||||
|
mvn package
|
||||||
|
|
@ -0,0 +1,72 @@
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>pp</groupId>
|
||||||
|
<artifactId>pp.12.01-ForkJoinArrayFilter_solution</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<exec.mainClass>pp.FilterTask</exec.mainClass>
|
||||||
|
<maven.compiler.release>10</maven.compiler.release>
|
||||||
|
<lombok.version>edge-SNAPSHOT</lombok.version>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
<dependencies>
|
||||||
|
<dependency><!-- für Unit-Tests -->
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter</artifactId>
|
||||||
|
<version>5.10.0</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency><!-- für Lombok -->
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>${lombok.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency><!-- für net.jcip Annotationen -->
|
||||||
|
<groupId>net.jcip</groupId>
|
||||||
|
<artifactId>jcip-annotations</artifactId>
|
||||||
|
<version>1.0</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<build>
|
||||||
|
<defaultGoal>clean compile exec:java</defaultGoal>
|
||||||
|
<plugins>
|
||||||
|
<plugin><!-- für Unit-Tests [mvn test] -->
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<version>3.0.0</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin><!-- [mvn compile] -->
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.9.0</version>
|
||||||
|
<configuration>
|
||||||
|
<annotationProcessorPaths>
|
||||||
|
<path>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>${lombok.version}</version>
|
||||||
|
</path>
|
||||||
|
</annotationProcessorPaths>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin><!-- [mvn exec:java] -->
|
||||||
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
|
<artifactId>exec-maven-plugin</artifactId>
|
||||||
|
<version>3.1.0</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin><!-- [mvn javadoc:javadoc] -->
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
|
<version>3.5.0</version>
|
||||||
|
<configuration>
|
||||||
|
<show>private</show>
|
||||||
|
<locale>en_US</locale>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
||||||
|
|
@ -0,0 +1,62 @@
|
||||||
|
package pp;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.concurrent.RecursiveAction;
|
||||||
|
import java.util.concurrent.ForkJoinPool;
|
||||||
|
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
public class FilterTask extends RecursiveAction {
|
||||||
|
|
||||||
|
private static final int ARRAY_LEN = 16;
|
||||||
|
private static final int SLICE_LEN = 4;
|
||||||
|
private static final int MAX = 10;
|
||||||
|
private static int instanceCounter = 0;
|
||||||
|
|
||||||
|
private final ArrayList<Integer> array;
|
||||||
|
private final int start;
|
||||||
|
private final int end;
|
||||||
|
|
||||||
|
FilterTask(ArrayList<Integer> array, int start, int end) {
|
||||||
|
this.array = array;
|
||||||
|
this.start = start;
|
||||||
|
this.end = end;
|
||||||
|
synchronized(FilterTask.class) {
|
||||||
|
FilterTask.instanceCounter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void compute() {
|
||||||
|
if ((this.end - this.start) <= SLICE_LEN) {
|
||||||
|
for (var i = this.start; i < this.end; i++) {
|
||||||
|
if (this.array.get(i) > MAX) {
|
||||||
|
this.array.set(i, MAX);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var mid = this.start + ((this.end - this.start) / 2);
|
||||||
|
var left = new FilterTask(this.array, this.start, mid);
|
||||||
|
var right = new FilterTask(this.array, mid, this.end);
|
||||||
|
left.fork();
|
||||||
|
right.fork();
|
||||||
|
right.join();
|
||||||
|
left.join();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String... args) {
|
||||||
|
var array = new ArrayList<Integer>();
|
||||||
|
for (var i = 0; i < ARRAY_LEN; i++) {
|
||||||
|
array.add(i + 1);
|
||||||
|
}
|
||||||
|
var task = new FilterTask(array, 0, array.size());
|
||||||
|
ForkJoinPool.commonPool().invoke(task);
|
||||||
|
for (var number : array) {
|
||||||
|
System.out.print(number + " ");
|
||||||
|
}
|
||||||
|
System.out.println("\nAnzahl der verwendeten Instanzen von FilterTask: "
|
||||||
|
+ FilterTask.instanceCounter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
# Laboraufgabe "Reduce als *divide and conquer*"
|
||||||
|
- [Aufgabenstellung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/12-02-ForkJoinArrayReduce.html)
|
||||||
|
- [Musterlösung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/12-Solutions.html#laboraufgabe-reduce-als-divide-and-conquer)
|
||||||
|
|
||||||
|
# Materialien
|
||||||
|
- [Folien](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/slides/12-forkjoin.html)
|
||||||
|
- [Skript](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/notes/12-forkjoin.html)
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
# Justfile (https://just.systems/) for starting Maven standard targets
|
||||||
|
|
||||||
|
default:
|
||||||
|
just exec pp.ReduceTask ""
|
||||||
|
|
||||||
|
exec class args: compile
|
||||||
|
mvn exec:java -Dexec.args="{{args}}" -Dexec.mainClass={{class}}
|
||||||
|
# exec class args:
|
||||||
|
# java -cp target/app.jar {{class}} {{args}}
|
||||||
|
clean:
|
||||||
|
mvn clean
|
||||||
|
compile:
|
||||||
|
mvn compile
|
||||||
|
test: compile
|
||||||
|
mvn test
|
||||||
|
javadoc:
|
||||||
|
mvn javadoc:javadoc
|
||||||
|
package:
|
||||||
|
mvn package
|
||||||
|
|
@ -0,0 +1,72 @@
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>pp</groupId>
|
||||||
|
<artifactId>pp.12.02-ForkJoinArrayReduce</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<exec.mainClass>pp.ReduceTask</exec.mainClass>
|
||||||
|
<maven.compiler.release>10</maven.compiler.release>
|
||||||
|
<lombok.version>edge-SNAPSHOT</lombok.version>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
<dependencies>
|
||||||
|
<dependency><!-- für Unit-Tests -->
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter</artifactId>
|
||||||
|
<version>5.10.0</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency><!-- für Lombok -->
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>${lombok.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency><!-- für net.jcip Annotationen -->
|
||||||
|
<groupId>net.jcip</groupId>
|
||||||
|
<artifactId>jcip-annotations</artifactId>
|
||||||
|
<version>1.0</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<build>
|
||||||
|
<defaultGoal>clean compile exec:java</defaultGoal>
|
||||||
|
<plugins>
|
||||||
|
<plugin><!-- für Unit-Tests [mvn test] -->
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<version>3.0.0</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin><!-- [mvn compile] -->
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.9.0</version>
|
||||||
|
<configuration>
|
||||||
|
<annotationProcessorPaths>
|
||||||
|
<path>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>${lombok.version}</version>
|
||||||
|
</path>
|
||||||
|
</annotationProcessorPaths>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin><!-- [mvn exec:java] -->
|
||||||
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
|
<artifactId>exec-maven-plugin</artifactId>
|
||||||
|
<version>3.1.0</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin><!-- [mvn javadoc:javadoc] -->
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
|
<version>3.5.0</version>
|
||||||
|
<configuration>
|
||||||
|
<show>private</show>
|
||||||
|
<locale>en_US</locale>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
package io.dama.ffi.forkjoin;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
public class ReduceTask {
|
||||||
|
|
||||||
|
private static final int ARRAY_LEN = 16;
|
||||||
|
private static final int SLICE_LEN = 4;
|
||||||
|
|
||||||
|
public static void main(String... args) {
|
||||||
|
var array = new ArrayList<Integer>();
|
||||||
|
for (var i = 0; i < ARRAY_LEN; i++) {
|
||||||
|
array.add(i + 1);
|
||||||
|
}
|
||||||
|
// initialen ReduceTask erzeugen
|
||||||
|
// ReduceTask im *Common Thread Pool* starten
|
||||||
|
// ReduceTask im *Common Thread Pool* starten
|
||||||
|
// auf Ende warten und Summe ausgeben
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
# Laboraufgabe "Reduce als *divide and conquer*"
|
||||||
|
- [Aufgabenstellung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/12-02-ForkJoinArrayReduce.html)
|
||||||
|
- [Musterlösung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/12-Solutions.html#laboraufgabe-reduce-als-divide-and-conquer)
|
||||||
|
|
||||||
|
# Materialien
|
||||||
|
- [Folien](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/slides/12-forkjoin.html)
|
||||||
|
- [Skript](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/notes/12-forkjoin.html)
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
# Justfile (https://just.systems/) for starting Maven standard targets
|
||||||
|
|
||||||
|
default: reduceTask
|
||||||
|
|
||||||
|
reduceTask:
|
||||||
|
just exec pp.ReduceTask ""
|
||||||
|
experiment:
|
||||||
|
just exec pp.ReduceTaskExperiment ""
|
||||||
|
generic:
|
||||||
|
just exec pp.ReduceTaskGeneric ""
|
||||||
|
threadsnumber:
|
||||||
|
just exec pp.ReduceTaskThreadsNumber ""
|
||||||
|
|
||||||
|
exec class args: compile
|
||||||
|
mvn exec:java -Dexec.args="{{args}}" -Dexec.mainClass={{class}}
|
||||||
|
# exec class args:
|
||||||
|
# java -cp target/app.jar {{class}} {{args}}
|
||||||
|
clean:
|
||||||
|
mvn clean
|
||||||
|
compile:
|
||||||
|
mvn compile
|
||||||
|
test: compile
|
||||||
|
mvn test
|
||||||
|
javadoc:
|
||||||
|
mvn javadoc:javadoc
|
||||||
|
package:
|
||||||
|
mvn package
|
||||||
|
|
@ -0,0 +1,72 @@
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>pp</groupId>
|
||||||
|
<artifactId>pp.12.02-ForkJoinArrayReduce_solution</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<exec.mainClass>pp.ReduceTask</exec.mainClass>
|
||||||
|
<maven.compiler.release>10</maven.compiler.release>
|
||||||
|
<lombok.version>edge-SNAPSHOT</lombok.version>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
<dependencies>
|
||||||
|
<dependency><!-- für Unit-Tests -->
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter</artifactId>
|
||||||
|
<version>5.10.0</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency><!-- für Lombok -->
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>${lombok.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency><!-- für net.jcip Annotationen -->
|
||||||
|
<groupId>net.jcip</groupId>
|
||||||
|
<artifactId>jcip-annotations</artifactId>
|
||||||
|
<version>1.0</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<build>
|
||||||
|
<defaultGoal>clean compile exec:java</defaultGoal>
|
||||||
|
<plugins>
|
||||||
|
<plugin><!-- für Unit-Tests [mvn test] -->
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<version>3.0.0</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin><!-- [mvn compile] -->
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.9.0</version>
|
||||||
|
<configuration>
|
||||||
|
<annotationProcessorPaths>
|
||||||
|
<path>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>${lombok.version}</version>
|
||||||
|
</path>
|
||||||
|
</annotationProcessorPaths>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin><!-- [mvn exec:java] -->
|
||||||
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
|
<artifactId>exec-maven-plugin</artifactId>
|
||||||
|
<version>3.1.0</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin><!-- [mvn javadoc:javadoc] -->
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
|
<version>3.5.0</version>
|
||||||
|
<configuration>
|
||||||
|
<show>private</show>
|
||||||
|
<locale>en_US</locale>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
package pp;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.concurrent.ForkJoinPool;
|
||||||
|
import java.util.concurrent.RecursiveTask;
|
||||||
|
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
public class ReduceTask extends RecursiveTask<Integer> {
|
||||||
|
|
||||||
|
private static int ARRAY_LEN = 16;
|
||||||
|
private static int SLICE_LEN = 4;
|
||||||
|
|
||||||
|
private final ArrayList<Integer> array;
|
||||||
|
private final int start;
|
||||||
|
private final int end;
|
||||||
|
|
||||||
|
ReduceTask(ArrayList<Integer> array, int start, int end) {
|
||||||
|
this.array = array;
|
||||||
|
this.start = start;
|
||||||
|
this.end = end;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Integer compute() {
|
||||||
|
var sum = 0;
|
||||||
|
if ((this.end - this.start) <= SLICE_LEN) {
|
||||||
|
for (var i = this.start; i < this.end; i++) {
|
||||||
|
sum += this.array.get(i);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var mid = this.start + ((this.end - this.start) / 2);
|
||||||
|
var left = new ReduceTask(this.array, this.start, mid);
|
||||||
|
var right = new ReduceTask(this.array, mid, this.end);
|
||||||
|
left.fork();
|
||||||
|
right.fork();
|
||||||
|
sum = left.join() + right.join();
|
||||||
|
}
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String... args) {
|
||||||
|
var array = new ArrayList<Integer>();
|
||||||
|
for (var i = 0; i < ARRAY_LEN; i++) {
|
||||||
|
array.add(i + 1);
|
||||||
|
}
|
||||||
|
var task = new ReduceTask(array, 0, array.size());
|
||||||
|
var sum = ForkJoinPool.commonPool().submit(task).join();
|
||||||
|
System.out.println("Summe: " + sum);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
package pp;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.concurrent.ForkJoinPool;
|
||||||
|
import java.util.concurrent.RecursiveTask;
|
||||||
|
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
public class ReduceTaskExperiment extends RecursiveTask<Integer> {
|
||||||
|
|
||||||
|
private static int ARRAY_LEN = 0;
|
||||||
|
private static int SLICE_LEN = 0;
|
||||||
|
|
||||||
|
private final ArrayList<Integer> array;
|
||||||
|
private final int start;
|
||||||
|
private final int end;
|
||||||
|
|
||||||
|
ReduceTaskExperiment(ArrayList<Integer> array, int start, int end) {
|
||||||
|
this.array = array;
|
||||||
|
this.start = start;
|
||||||
|
this.end = end;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Integer compute() {
|
||||||
|
var sum = 0;
|
||||||
|
if ((this.end - this.start) <= SLICE_LEN) {
|
||||||
|
for (var i = this.start; i < this.end; i++) {
|
||||||
|
sum += this.array.get(i);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var mid = this.start + ((this.end - this.start) / 2);
|
||||||
|
var left = new ReduceTaskExperiment(this.array, this.start, mid);
|
||||||
|
var right = new ReduceTaskExperiment(this.array, mid, this.end);
|
||||||
|
left.fork();
|
||||||
|
right.fork();
|
||||||
|
sum = left.join() + right.join();
|
||||||
|
}
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String... args) {
|
||||||
|
for (ARRAY_LEN = 100; ARRAY_LEN < 10000000; ARRAY_LEN = ARRAY_LEN
|
||||||
|
* 10) {
|
||||||
|
for (SLICE_LEN = 4; SLICE_LEN < 128; SLICE_LEN = SLICE_LEN * 2) {
|
||||||
|
var array = new ArrayList<Integer>();
|
||||||
|
for (var i = 0; i < ARRAY_LEN; i++) {
|
||||||
|
array.add(i + 1);
|
||||||
|
}
|
||||||
|
var now = System.currentTimeMillis();
|
||||||
|
var task = new ReduceTaskExperiment(array, 0, array.size());
|
||||||
|
var sum = ForkJoinPool.commonPool().submit(task).join();
|
||||||
|
System.out.printf(
|
||||||
|
"ARRAY_LEN: %d, SLICE_LEN: %d, Summe: %d, Zeit: %d \n",
|
||||||
|
ARRAY_LEN, SLICE_LEN, sum,
|
||||||
|
System.currentTimeMillis() - now);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,86 @@
|
||||||
|
package pp;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.concurrent.ForkJoinPool;
|
||||||
|
import java.util.concurrent.RecursiveTask;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
public class ReduceTaskGeneric<T> extends RecursiveTask<T> {
|
||||||
|
// Der Typ der Elemente im Container ist T (statt Integer).
|
||||||
|
// Dieser Typ wird Parameter von ReduceTaskGeneric.
|
||||||
|
|
||||||
|
private static int ARRAY_LEN = 16;
|
||||||
|
private static int SLICE_LEN = 4;
|
||||||
|
|
||||||
|
private final ArrayList<T> array;
|
||||||
|
private final int start;
|
||||||
|
private final int end;
|
||||||
|
|
||||||
|
// generische Lösung: statt + wird die BiFunction aggregateFunc benutzt
|
||||||
|
// aggregateFunc ist ein Objekt, das die Funktion
|
||||||
|
// T apply(T x, T y)
|
||||||
|
// beinhaltet. Sie wird später statt + aufgerufen
|
||||||
|
private final BiFunction<T, T, T> aggregFun;
|
||||||
|
// als Start wird ein Ersatz für 0 benötigt. Dieser initiale Wert muss vom
|
||||||
|
// Typ T
|
||||||
|
// sein
|
||||||
|
private final T initAcc;
|
||||||
|
|
||||||
|
ReduceTaskGeneric(BiFunction<T, T, T> aggregFun, T initAcc,
|
||||||
|
ArrayList<T> array, int start, int end) {
|
||||||
|
this.array = array;
|
||||||
|
this.start = start;
|
||||||
|
this.end = end;
|
||||||
|
// generische Lösung: aggregFun und initAcc müssen über den Konstruktor
|
||||||
|
// übergeben werden
|
||||||
|
this.aggregFun = aggregFun;
|
||||||
|
this.initAcc = initAcc;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected T compute() { // satt Integer T als Rückgabetyp
|
||||||
|
var accumulator = this.initAcc; // statt 0 initAcc
|
||||||
|
if ((this.end - this.start) <= SLICE_LEN) {
|
||||||
|
for (var i = this.start; i < this.end; i++) {
|
||||||
|
// statt + aggregFun.apply
|
||||||
|
accumulator = this.aggregFun.apply(accumulator,
|
||||||
|
this.array.get(i));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var mid = this.start + ((this.end - this.start) / 2);
|
||||||
|
var left = new ReduceTaskGeneric<>(this.aggregFun, this.initAcc,
|
||||||
|
this.array, this.start, mid);
|
||||||
|
var right = new ReduceTaskGeneric<>(this.aggregFun, this.initAcc,
|
||||||
|
this.array, mid, this.end);
|
||||||
|
left.fork();
|
||||||
|
right.fork();
|
||||||
|
|
||||||
|
// statt + aggregFun.apply
|
||||||
|
accumulator = this.aggregFun.apply(left.join(), right.join());
|
||||||
|
}
|
||||||
|
return accumulator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String... args) {
|
||||||
|
var array = new ArrayList<Integer>();
|
||||||
|
for (var i = 0; i < ARRAY_LEN; i++) {
|
||||||
|
array.add(i + 1);
|
||||||
|
}
|
||||||
|
// Hier wird die aggregFun als Lambda-Ausdruck übergeben: (a, b) -> a +
|
||||||
|
// b
|
||||||
|
// Der Typ-Parameter von ReduceTaskGeneric wird dementsprechend auf
|
||||||
|
// Integer
|
||||||
|
// festgelegt.
|
||||||
|
// Der initiale Wert des +-Akkumulators ist 0
|
||||||
|
var task = new ReduceTaskGeneric<>(//
|
||||||
|
((a, b) -> a + b), // Hier wird die aggregFun als
|
||||||
|
// Lambda-Ausdruck übergeben: +
|
||||||
|
0, // Der initiale Wert des +-Akkumulators ist 0.
|
||||||
|
array, 0, array.size());
|
||||||
|
ForkJoinPool.commonPool().invoke(task);
|
||||||
|
// seit Java 8 alternativ: task.invoke();
|
||||||
|
var sum = task.join();
|
||||||
|
System.out.println("Summe: " + sum);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
package pp;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.concurrent.ForkJoinPool;
|
||||||
|
import java.util.concurrent.RecursiveTask;
|
||||||
|
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
public class ReduceTaskThreadsNumber extends RecursiveTask<Integer> {
|
||||||
|
|
||||||
|
private static int ARRAY_LEN = 280;
|
||||||
|
private static int SLICE_LEN = ARRAY_LEN / ForkJoinPool.commonPool().getParallelism();
|
||||||
|
private static int instanceCounter = 0;
|
||||||
|
|
||||||
|
private final ArrayList<Integer> array;
|
||||||
|
private final int start;
|
||||||
|
private final int end;
|
||||||
|
|
||||||
|
ReduceTaskThreadsNumber(ArrayList<Integer> array, int start, int end) {
|
||||||
|
this.array = array;
|
||||||
|
this.start = start;
|
||||||
|
this.end = end;
|
||||||
|
instanceCounter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Integer compute() {
|
||||||
|
var sum = 0;
|
||||||
|
if ((this.end - this.start) <= SLICE_LEN) {
|
||||||
|
for (var i = this.start; i < this.end; i++) {
|
||||||
|
sum += this.array.get(i);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var mid = this.start + ((this.end - this.start) / 2);
|
||||||
|
var left = new ReduceTaskThreadsNumber(this.array, this.start, mid);
|
||||||
|
var right = new ReduceTaskThreadsNumber(this.array, mid, this.end);
|
||||||
|
left.fork();
|
||||||
|
right.fork();
|
||||||
|
sum = left.join() + right.join();
|
||||||
|
}
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String... args) {
|
||||||
|
var array = new ArrayList<Integer>();
|
||||||
|
for (var i = 0; i < ARRAY_LEN; i++) {
|
||||||
|
array.add(i + 1);
|
||||||
|
}
|
||||||
|
var task = new ReduceTaskThreadsNumber(array, 0, array.size());
|
||||||
|
var sum = ForkJoinPool.commonPool().submit(task).join();
|
||||||
|
System.out.println("Summe: " + sum);
|
||||||
|
System.out.println("instanceCounter: " + instanceCounter);
|
||||||
|
System.out.println(
|
||||||
|
"Parallelism: " + ForkJoinPool.commonPool().getParallelism());
|
||||||
|
System.out.println("ARRAY_LEN: " + ARRAY_LEN);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue