Ich möchte einen Algorithmus auf großen Diagrammen gleichzeitig unter Verwendung der Mehrkernparallelität laufen lassen. Ich habe eine Weile daran gearbeitet, konnte mir aber keine gute Lösung einfallen lassen.Wie man einen Graphalgorithmus gleichzeitig in Java unter Verwendung der Mehrkernparallelität laufen lässt
Dies ist der naive Algorithmus:
W - a very large number
double weight = 0
while(weight < W)
- v : get_random_node_from(Graph)
- weight += calculate(v)
- Ich sah in Gabel-and-schließen, kann aber nicht einen Weg finden, um dieses Problem in kleinere Teilprobleme zu teilen.
- Dann versuchte ich Java 8 Streams, für die ich einen Lambda-Ausdruck erstellen muss. Als ich versuchte, so etwas wie dies zu tun:
double weight = 0 Callable<Object> task =() -> { can not update weight here, as it needs to be final }
Meine Frage ist, ist es möglich, eine Variable wie weight
in einem Lambda-Verfahren zu aktualisieren? Oder gibt es einen besseren Weg, dieses Problem zu lösen?
Die nächste, die ich habe, ist mit ExecutorService
, aber laufen Sie auf die Probleme der Synchronisation.
------------ EDIT --------------
Hier ist die detaillierte Algorithmus:
In Kurz gesagt, was ich versuche zu tun, ist ein riesiger Graph zu durchlaufen, eine Operation an zufällig ausgewählten Knoten durchzuführen (solange Gewicht < W) und einen globalen Strukturindex zu aktualisieren.
Dies dauert zu lange, da es nicht die volle Leistung der CPU nutzt.
Idealerweise alle Fäden/Prozesse auf mehrere Kerne würden die Operationen an den zufällig ausgewählten Knoten führen, und aktualisieren den freigegebenen Gewicht und Index.
Hinweis: Es spielt keine Rolle, wenn verschiedene Threads den gleichen Knoten aufnehmen, da es ohne Ersatz zufällig ist.
Algorithmus:
Funktion Serien() {
List<List<Integer>> I (shared data structure which I want to update)
double weight
//// Task which I want to parallelize
while(weight < W) {
v : get_random_node_from(Graph)
bfs(v, affected_nodes) ...// this will fill up affected_nodes by v
foreach(affected_node in affected_nodes) {
// update I related to affected_node
// and do other computation
}
weight += affected_nodes.size()
}
///////// Parallelization ends here
use_index(I) // I is passed now to some other method(not important) to get further results
}
Das Wichtigste ist, aktualisieren Sie alle Threads die gleiche I
und weight
.
Danke.
Ich bin mir nicht sicher, was Sie erreichen wollen - wenn Sie das Gewicht des gesamten Graphen mit Java-Streams berechnen möchten, würden Sie jedes Element des Streams nur als Knoten des Graphen verwenden, verwenden Sie map to Ordne es dem Gewicht zu, summiere dann den Strom. Das sollte auch parellisierbar sein. – russianmario
Lassen Sie 'Gewicht = W'. Sollten andere Berechnungen abgebrochen werden oder können sie ihre Arbeit beenden? Wenn sie ihre Arbeit beenden können und sollten sie ihre Ergebnisse zu "Gewicht" hinzufügen? –
@AlexeiKaigorodov Immer wenn 'Gewicht> W 'alle Prozesse sollten aufhören. Ich werde die Frage bearbeiten, um weitere Details hinzuzufügen. – akshayKhot