2012-05-12 55 views
6

我有一個封閉的源非線程安全的C++共享庫,它提供了一個函數f :: ByteString - > ByteString。這個函數的運行時間可以在1秒到幾個小時之間。Haskell框架並行化非線程安全C++庫

我正在尋找一種方法將計算分配給多個核心/服務器(SIMD)。

概括地說,我在尋找一個能提供功能

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

解除了,只能按順序叫成表現得像在Haskell任何其他純函數的函數功能的框架。

舉例來說,我希望能寫:

parMap rwhnf f args -- will not work 

因爲f調用通過FFI非線程安全的LIB C函數,這是不行的。因此,我可以用函數g替換函數f,該函數保存作業隊列並將任務分派給N個獨立的進程。該過程可以在本地運行或分佈式:

parMap rwhnf g args -- should works 

潛在的框架,我已經看着是

  1. MPI:客戶端(哈斯克爾)< - MPI - >代理(C++)< - - MPI - >工(C++)< - >庫(C++)

  2. ZeroMQ:客戶端(Haskell中)< - ZeroMQ - >代理(C++)< - ZeroMQ - >工(C++)< - >庫(C++)

  3. 雲的Haskell:客戶端(Haskell的)< - CloudHaskell - >工人(Haskell的)< - FFI - >庫(C++)

  4. 的Gearman

  5. 二郎:客戶端(Haskell的)< - 二郎 - >代理(二郎)< - - Erlang CN ode - > Worker(C++)

每種方法都有優點和缺點。

  1. MPI將產生很多安全問題,是一個相當重的解決方案。

  2. ZeroMQ是一個不錯的解決方案,但要求我自己編寫代理/負載均衡器等(尤其是獲得可靠性並不重要)。

  3. CloudHaskell看起來不太成熟。

  4. Gearman不能在Windows上運行,並且沒有Haskell綁定。我知道java-gearman-service,但它不如C守護程序成熟,還有一些其他問題(例如,如果沒有任何流入任務的文檔,會關閉,等等)。

  5. 與1類似,需要使用第三種語言。

謝謝!

+0

您正在研究將相同數據的函數分發到多個內核以使其安全失效?如果沒有,那麼你的閉源函數怎麼可以並行化呢? –

+0

我正在尋找SIMD解決方案。封閉的源代碼意味着我不能對lib本身進行任何修改,以使其對線程安全。因此,我將不得不在一個單獨的進程中運行每個函數調用。我正在尋找的是一個用於負載平衡/連接過程的簡單解決方案。在Scala中,我會將工作人員用作Akka作爲遠程節點,並在單獨的JVM中運行。 – Chronos

+1

啊,所以你想在不同的輸入上多次計算函數?這從你的問題來看並不完全清楚,你可能想編輯第一句話來提及它:) –

回答

1

由於您使用的庫不是線程安全的,因此您希望基於使用進程的解決方案作爲您的並行抽象。你希望看到使用Par monad的例子使用基於spark或task的並行模型,其中許多火花可以存在於同一個線程中。顯然這不是你要找的。

不怕!

Haskell中只有少數幾種工作方式以這種方式工作,您在您的文章Cloud Haskell中提到了其中的一種。儘管Cloud Haskell尚未「成熟」,但它可以解決您的問題,但它可能會對您的需求有點重量級。如果你真的只需要承擔使用過程級並行抽象許多地方的核心優勢,然後看看在伊甸園庫:

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

伊甸園你完全可以表達你所追求的。這裏是沿着你的面值單子基於版本的線條很簡單的例子:

f $# args 

或者在許多參數的情況下,你可能只是拔出葉奧爾德地圖:

map f $# args 

有關的更多信息在$#語法和有關伊甸園教程參見:

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

因人而異,因爲大多數在Haskell比較成熟的並行範式假設你哈具有一定程度的線程安全性或使用可以以純粹的方式完成並行工作。

好運和快樂黑客!

+0

太好了 - 謝謝!我會看一下。 – Chronos