2010-08-19 7 views

Antwort

4
+0

Ich versuchte es in der Tiefe zu erklären, hier: [Java: mit der Fork/Join-Framework für die parallele Auflösung von Divide-and-Conquer-Problemen] (http://www.davismol.net/2016/ 01/24/java-using-the-forkjoin-framework-for-the-parallel-resolution-of-divide-and-conquer-probleme /) –

2

Sagen Sie eine Sammlung von Dingen, die verarbeitet werden müssen. Sie haben eine Reihe von Threads, die Teilmengen dieser Sammlung erfassen und verarbeiten können. Sie alle tun dies gleichzeitig (der Fork-Teil) und warten dann auf den letzten, um zu beenden (der Join-Teil), bevor sie zurückkehren.

+0

Mit dem priviso, dass das aktuelle parent _stop das Ausführen_ abschließt, bis alle konkurrierenden Workers abgeschlossen sind. und dann wird fortgesetzt. Ich weiß, dass das Ihrer Beschreibung innewohnte, aber ich denke, es ist es wert, sehr explizit zu sein, denn das ist es, was dies wirklich von anderen expliziten Parallelen unterscheidet. – Gian

+0

Nun, es ist nicht eine Gabelung von Operationen, führen Sie sie alle und dann beitreten. Es ist ein Teil-und-herrsche-Ansatz. –

8

Fork Join ist ein neues Framework, das eine leichter zu verwenden API für einen parallelen, Teile und Herrsche-Algorithmus hat.

Sagen Sie bitte eine lange laufende Aufgabe haben, die für diese Instanz, einen komplizierten Algorithmus hat. Sie möchten die großen Aufgaben aufteilen und jetzt an diesen beiden Aufgaben arbeiten. Nun, sagen wir, dass diese zwei Aufgaben immer noch zu groß sind, würden Sie jede in zwei Aufgaben (an dieser Stelle sind es vier).

Sie würden weitermachen, bis jede Aufgabe mit einer akzeptablen Größe und den Algorithmus aufzurufen. Es ist wichtig zu wissen, dass der Aufruf jeder Aufgabe parallel erfolgt. Wenn die Aufgabe abgeschlossen ist, wird sie mit der anderen Aufgabe verknüpft, mit der sie gegabelt wurde, und die Ergebnisse werden konsolidiert.

Dies wird fortgesetzt, bis alle Aufgaben wieder verbunden worden sind und eine Aufgabe.

3

Zusätzlich zu dem, was bereits gesagt, Gabel/join nutzt Arbeit zu stehlen - Threads, die aus den Dingen Aufgaben von anderen Threads zu tun stehlen kann, die noch beschäftigt sind. Und hier ist ein Beispiel, das Ihnen helfen kann zu verstehen, wie FJ verwendet werden können:

public class SumCounter extends RecursiveTask<Long> { 

    private final Node node; 

    public SumCounter(Node node) { 
    this.node = node; 
    } 

    @Override 
    protected Long compute() { 
    long sum = node.getValue(); 
    List<ValueSumCounter> subTasks = new LinkedList<>(); 

    for(Node child : node.getChildren()) { 
     SumCounter task = new SumCounter(child); 
     task.fork(); // run asynchronously 
     subTasks.add(task); 
    } 

    for(SumCounter task : subTasks) { 
     sum += task.join(); // wait for the result 
    } 

    return sum; 
    } 

    public static void main(String[] args) { 
    Node root = getRootNode(); 
    new ForkJoinPool().invoke(new SumCounter(root)); 
    } 

} 
1

Let Ich habe nur meine zwei Cent, um das grundlegende Verständnis von Fork/Join einfach zu machen.

What is Fork/Join? 

The fork/join framework is an implementation of the ExecutorService interface 
that helps you take advantage of multiple processors. It is designed for work 
that can be broken into smaller pieces recursively. The goal is to use all the 
available processing power to enhance the performance of your application. 
  • Dieser Rahmen ist sehr nützlich für die Modellierung von Teile-und-Herrsche Probleme. Dieser Ansatz ist für Aufgaben geeignet, die rekursiv unterteilt und in kleinerem Maßstab berechnet werden können; Die berechneten Ergebnisse sind dann kombiniert.
  • Das Framework ist eine Implementierung der ExecutorService-Schnittstelle und bietet eine einfach zu bedienende gleichzeitige Plattform, um mehrere Prozessoren auszunutzen.

Begriff, die für diesen Rahmen

  • Forking: Teilt man die Aufgabe in kleinere Aufgaben gabelt.
  • Joining: Zusammenführen der Ergebnisse aus den kleineren Aufgaben beitritt

Wie bei jeder ExecutorService Implementierung wird die Gabel/beitreten Rahmen Aufgaben Arbeitsthreads in einem Thread-Pool verteilt. Das Fork/Join-Framework ist eindeutig, da es einen Arbeitsstehlgorithmus verwendet. Worker-Threads, denen keine Aufgaben mehr zur Verfügung stehen, können Aufgaben von anderen noch aktiven Threads stehlen.

Der Fork/Join-Algorithmus ist wie folgt aufgebaut:

  • geteilte Aufgaben
  • Gabel die Aufgaben
  • kommen Sie mit den Aufgaben
  • komponieren die Ergebnisse
doRecursiveTask(input){ 
    if(task is small enough to handled by a thread){ 
     compute the small task; 
     if there is result to return, then do so 
    }else{ 
     divide the task i.e, fork() into two parts 
     call compute on first task, join on second task, combine both results and return 
    } 
} 

Was ist Arbeit-Diebstahl-Algorithmus?

Jeder Arbeiter-Thread in der Gabel ihr/Join Rahmen eine Arbeitsschlange, die einen Deque realisiert wird. Jedes Mal, wenn eine neue Task (oder Subtask) erstellt wird, wird sie an den Anfang ihrer eigenen Warteschlange geschoben. Wenn eine Aufgabe eine Aufgabe abschließt und eine Verknüpfung mit einer anderen Aufgabe ausführt, die noch nicht abgeschlossen ist, funktioniert es intelligent. Der Thread ruft eine neue Task aus dem Kopf der Warteschlange auf und startet die Ausführung statt der Ruhe (in der Reihenfolge , um darauf zu warten, dass eine andere Task abgeschlossen wird). Wenn die Warteschlange eines -Threads leer ist, ruft der Thread eine Task aus dem Ende der -Warteschlange auf, die zu einem anderen Thread gehört. Dies ist nichts anderes als ein arbeitsstehlender Algorithmus. More detail is here