Haskell框架,用于并行化非线程安全的C++库

Chr*_*nos 6 concurrency haskell distributed-computing gearman zeromq

我有一个闭源非线程安全的C++共享库,它提供了一个函数f :: ByteString - > ByteString.此功能的运行时间可能介于一秒到几个小时之间.

我正在寻找一种方法将计算分配到多个核心/服务器(SIMD).

简而言之,我正在寻找一个提供功能的框架

    g :: Strategy b -> (a -> b) -> a -> b
Run Code Online (Sandbox Code Playgroud)

提升一个只能被顺序调用到一个函数的函数,该函数的行为类似于Haskell中的任何其他纯函数.

例如,我希望能够写:

    parMap rwhnf f args -- will not work
Run Code Online (Sandbox Code Playgroud)

由于f通过FFI在非线程安全的lib中调用C函数,因此不起作用.因此,我可以用函数g替换函数f,函数g保存作业队列并将任务分派给N个单独的进程.这些进程可以在本地运行或分发:

    parMap rwhnf g args -- should works
Run Code Online (Sandbox Code Playgroud)

我已经研究过的潜在框架是

  1. MPI:客户端(Haskell)< - MPI - >代理(C++)< - MPI - >工作者(C++)< - > Lib(C++)

  2. ZeroMQ:客户端(Haskell)< - ZeroMQ - > Broker(C++)< - ZeroMQ - > Worker(C++)< - > Lib(C++)

  3. Cloud Haskell:客户端(Haskell)< - CloudHaskell - > Worker(Haskell)< - FFI - > Lib(C++)

  4. Gearman的

  5. Erlang:Client(Haskell)< - Erlang - > Broker(Erlang)< - Erlang C Node - > Worker(C++)

每种方法都有优点和缺点.

  1. MPI将产生许多安全问题,并且是一个非常重量级的解决方案.

  2. ZeroMQ是一个很好的解决方案,但需要我自己编写代理/负载均衡器等(特别是获得正确的可靠性并非易事).

  3. CloudHaskell看起来不太成熟.

  4. Gearman不能在Windows上运行,也没有Haskell绑定.我知道java-gearman-service,但它远不如C守护进程成熟,还有其他一些问题(例如没有doc,如果一段时间内没有任务传入,则关闭等等).

  5. 与1类似,需要使用第三种语言.

谢谢!

小智 1

由于您使用的库不是线程安全的,您需要一个基于使用进程作为并行性抽象的解决方案。您希望看到的使用 Par monad 的示例使用基于 Spark 或任务的并行模型,其中许多 Spark 可以存在于同一线程中。显然这不是您正在寻找的。

不要害怕!

Haskell 中只有少数范例以这种方式工作,您在文章 Cloud Haskell 中提到了其中之一。虽然 Cloud Haskell 还不“成熟”,但它可以解决您的问题,但对于您的需求来说,它可能有点重量级。如果您确实只需要使用进程级并行抽象来利用许多本地核心,那么请查看 Eden 库:

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

有了 Eden,您绝对可以表达您的追求。这是一个非常简单的示例,类似于基于 Par Monad 的版本:

f $# args
Run Code Online (Sandbox Code Playgroud)

或者,在有很多争论的情况下,你可能只是拿出旧地图:

map f $# args
Run Code Online (Sandbox Code Playgroud)

有关 $# 语法的更多信息以及有关 Eden 的教程,请参阅:

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

YMMV 作为 Haskell 中大多数更成熟的并行范例假设您具有一定程度的线程安全性,或者使用可以以纯粹的方式完成并行工作。

祝你好运,黑客快乐!