2012-05-12 4 views
6

Ich habe eine geschlossene Quelle nicht-threadsafe C++ freigegebene Lib, die eine Funktion f :: ByteString -> ByteString bietet. Die Laufzeit dieser Funktion kann zwischen einer Sekunde und einigen Stunden liegen.Haskell Framework parallel zu non-threadsafe C++ Lib

Ich bin auf der Suche nach einer Möglichkeit, die Berechnung auf mehrere Kerne/Server (SIMD) zu verteilen.

Auf den Punkt gebracht, ich bin auf der Suche nach einem Rahmen, der eine Funktion

g :: Strategy b -> (a -> b) -> a -> b 

heben eine Funktion bereitstellt, die nur sequentiell in eine Funktion aufgerufen werden kann, die wie jede andere reine Funktion in Haskell verhält.

Zum Beispiel ich möchte in der Lage sein, zu schreiben:

parMap rwhnf f args -- will not work 

Da f eine C-Funktion in einer nicht-Thread-sichere lib über FFI nennt, das wird nicht funktionieren. Daher könnte ich die Funktion f durch eine Funktion g ersetzen, die eine Jobwarteschlange enthält und die Tasks an N separate Prozesse verteilt. Die Prozesse können lokal oder verteilt laufen:

parMap rwhnf g args -- should works 

Mögliche Frameworks Ich sah bereits in sind

  1. MPI: Client (Haskell) < - MPI -> Broker (C++) < - - MPI -> Arbeiter (C++) < -> Lib (C++)

  2. ZeroMQ: Client (Haskell) < - ZeroMQ -> Broker (C++) < - ZeroMQ -> Arbeiter (C++) < -> Lib (C++)

  3. Wolke Haskell: Client (Haskell) < - CloudHaskell - > Arbeiter (Haskell) < - FFI -> Lib (C++)

  4. Gearman

  5. Erlang: Client (Haskell) < - Erlang -> Broker (Erlang) < - - Erlang CN ode -> Arbeiter (C++)

Jeder Ansatz hat Vor- und Nachteile.

  1. MPI wird viele Sicherheitsprobleme verursachen und ist eine ziemlich schwere Lösung.

  2. ZeroMQ ist eine nette Lösung, aber würde erfordern, dass ich den Broker/Load Balancer etc. ganz alleine schreibe (besonders die Zuverlässigkeit zu bekommen ist nicht trivial).

  3. CloudHaskell sieht nicht sehr ausgereift aus.

  4. Gearmman läuft nicht unter Windows und hat keine Haskell-Bindungen.Ich weiß über Java-Gearman-Service, aber es ist viel weniger reif als der C-Daemon und hat einige andere Probleme (z. B. kein doc, schaltet sich ab, wenn es für einige Zeit keine eingehenden Aufgaben gibt, etc.).

  5. Ähnlich wie 1 und erfordert die Verwendung einer dritten Sprache.

Vielen Dank!

+0

Sie arbeiten daran, eine Funktion zu verteilen, die mit denselben Daten auf mehreren Kernen arbeitet, um sie fehlerfrei zu machen? Wenn nicht, wie kann Ihre Closed-Source-Funktion parallelisiert werden? –

+0

Ich suche eine SIMD-Lösung. Closed Source bedeutet, dass ich die lib selbst nicht modifizieren kann, um sie threadsicher zu machen. Daher muss ich jeden Funktionsaufruf in einem separaten Prozess ausführen. Was ich suche, ist eine einfache Lösung zum Lastenausgleich/Verbinden der Prozesse. In Scala würde ich Akka mit Arbeitern als Remote-Knoten verwenden, die in einer separaten JVM ausgeführt werden. – Chronos

+1

ah, also willst du die Funktion mehrfach an verschiedenen Eingängen berechnen? das ist überhaupt nicht klar von deiner Frage, du möchtest vielleicht die ersten paar Sätze bearbeiten, um es zu erwähnen :) –

Antwort

1

Da die von Ihnen verwendete Bibliothek nicht Thread-sicher ist, möchten Sie eine Lösung, die Prozesse als Abstraktion für Parallelität verwendet. Das Beispiel, das Sie mit der Par-Monade sehen möchten, verwendet das funken- oder aufgabenbasierte Parallelitätsmodell, in dem viele Funken in demselben Thread leben können. Das ist eindeutig nicht das, wonach Sie suchen.

Angst nicht!

Es gibt nur ein paar Paradigmen in Haskell, die auf diese Weise funktionieren, und Sie haben eines davon in Ihrem Beitrag, Cloud Haskell, erwähnt. Obwohl Cloud Haskell nicht "ausgereift" ist, könnte es Ihre Probleme lösen, aber es könnte ein kleines Schwergewicht für Ihre Bedürfnisse sein. Wenn Sie wirklich nur die Vorteile der vielen lokalen Kerne nehmen müssen mit Blick die Prozessebene parallel Abstraktion dann im Eden Bibliothek:

http://www.mathematik.uni-marburg.de/~eden/

Mit Eden können Sie absolut ausdrücken, was Sie nach. Hier ist ein sehr einfaches Beispiel entlang der Linien Ihrer Par Monad basierte Version:

f $# args 

Oder im Fall von vielen Argumenten können Sie nur ye olde Karte herausziehen:

map f $# args 

Weitere Informationen zu die $ # Syntax und Tutorials über Eden sehen:

http://www.mathematik.uni-marburg.de/~eden/paper/edenCEFP.pdf

YMMV wie die meisten der reiferen parallel Paradigmen in Haskell annehmen, dass Sie ha Ein gewisses Maß an Sicherheit für den Faden oder die Verwendung kann die parallele Arbeit in einer reinen Weise tun.

Viel Glück und Happy Hacking!

+0

Großartig - Danke! Ich werde nachsehen. – Chronos