Wie kann ich mit Clojure die Summe einer großen Anzahl von Zahlen parallel berechnen?

8

Ich versuche herauszufinden, wie man mit clojure eine einfache Operation effizient parallel auf eine große Sequenz anwenden kann. Ich möchte in der Lage sein, die parallele Lösung zu verwenden, um die Vorteile der mehreren Kerne auf meiner Maschine zu nutzen, um eine gewisse Beschleunigung zu erreichen.

Ich versuche, pmap in Kombination mit "all-partition" zu verwenden, um den Aufwand für das Erstellen einer Zukunft für jedes Element im Eingabe-Seq zu reduzieren. Leider zwingt Partition-all die vollständige Auswertung jeder Partition Seq. Das verursacht einen OutOfMemoryError auf meinem Computer.

%Vor%

Wie kann ich die Summe auf einen großen Eingabesatz anwenden und die Leistung der seriellen Implementierung übertreffen?

Lösung

Danke an @Arthur Ulfeldt für den Hinweis auf die Reducer-Bibliothek. Hier ist die Lösung mit Reduzierern. Dieser Code zeigt die erwartete Leistungsverbesserung beim Ausführen auf einem Multicore-Computer. (HINWEIS: Ich habe vs geändert, um eine Funktion zu sein, um das Timing genauer zu machen)

%Vor%     
John Atwood 11.02.2013, 17:59
quelle

1 Antwort

8

Bei der Verwendung von pmap habe ich festgestellt, dass ziemlich große Chunks benötigt werden, um den Wechsel und zukünftigen Overhead zu überwinden. Versuchen Sie eine Chunk-Größe von 10.000 für eine Operation so schnell wie + . Die potentiellen Gewinne sind durch den Aufwand zum Erzeugen der Stücke begrenzt. Dies ergibt einen optimalen Wert, der die verfügbaren Kerne und die Zeit, die zum Herstellen der Blöcke benötigt wird, ausgleicht. In diesem Fall mit + als Workload konnte ich das nicht schneller machen als die Single-Thread-Option.

Wenn Sie daran interessiert sind, dies ohne pmap zu tun und möglicherweise fork / join zu verwenden, schauen Sie sich das neue (ish) Reduzierbibliothek

Die OOM-Situation stammt aus dem ersten Test, der die Lazy-Sequenz von (range n) realisiert, die dann beibehalten wird, damit sie an die zweite Sequenz übergeben werden kann.

Wenn ich die Funktion + viel langsamer mache, indem ich eine Funktion slow+ definiere und verwende, dass die Diference zwischen einzelnen Threads, pmap über Chunks und Reducern mit forkJoin sichtbar wird:

%Vor%     
Arthur Ulfeldt 11.02.2013, 18:47
quelle

Tags und Links