Haskell如何处理多核机器/集群上的并行计算

时间:2017-06-06 14:59:12

标签: multithreading haskell concurrency cluster-computing

我正在考虑使用一种新语言来学习那些在我们拥有的计算机集群中用于高性能计算的日子,在这些语言中,我正在考虑使用Haskell。

我已经阅读了一些关于Haskell的内容,但是仍然有关于在高性能和分布式计算中使用Haskell的问题,这种语言是众所周知的,但我读到一些关于Haskell的争论因懒惰而对这类系统不利,我可以用以下几行总结我的问题:

  1. Haskell使用绿色线程,这对于处理大量并发连接非常有用,但当其中一个任务占用时间超过平均值并阻塞其余任务时会发生什么,整个线程阻塞(Node.js样式),将下一个任务转发到另一个处理器/线程(Golang),使用reductions技术(Erlang),在预定数量的滴答之后将任务从处理上下文中踢出,否则?

  2. 在分布式计算环境中,懒惰评估函数会发生什么,是否必须强制执行?

  3. 如果一个函数/模块需要严格的评估,但它依赖于其他惰性函数/模块,我是否应该修改其他函数/模块的代码以使它们严格,或者编译器会处理这个并强迫该链条中的所有内容严格或懒惰。

  4. 当处理一个非常大的数据序列时,Haskell如何处理并行处理,是通过遵循某种隐式map-reduce技术,还是我自己做的。

  5. 语言中是否有一个聚类摘要,它为我处理计算能力,它会自动将下一个任务转发到免费处理器,无论它在同一台计算机上,还是在同一个集群中的另一台计算机上

  6. Haskell如何确保公平分享工作均匀分布到同一台计算机或可用群集上的所有可用核心。

2 个答案:

答案 0 :(得分:8)

  1. GHC使用可用工作池(称为 sparks )和work-stealing系统:当线程用完工作时,它将在池中查找工作或在其他可以窃取的线程的工作队列中。

  2. 对于分布式计算没有内置支持,因为(例如)Erlang。语义是您的实现定义的任何内容。现有的实施工具如Cloud Haskell,您可以查看示例。

  3. 都不是。 Haskell将自动执行任何必要的工作,以提供所需的值,而不再需要。

  4. Haskell(特别是GHC)没有做任何事情来自动并行化评估,因为没有已知的并行化通用策略,它比非并行化更好。有关详细信息,请参阅Why is there no implicit parallelism in Haskell?

  5. 没有。见(2)。

  6. 对于同一台机器,它使用上面描述的火花池和工作窃取系统。没有“聚类”的概念。

  7. 有关Haskell中并行和并发编程的概述,请参阅GHC运行时系统的主要作者Simon Marlow的free book of the same name

答案 1 :(得分:6)

多线程

就SMP p arallelism 而言,Haskell非常有效。这是not quite automatic,但是parallel library可以很容易地将任何内容并行化。因为火花非常便宜,你可能会非常粗心,只需要求很多的并行性;运行时将知道该怎么做 与大多数其他语言不同,如果您拥有高度分支的数据结构,棘手的动态算法等,这不是一个大问题 - 由于纯粹的功能范例,并行Haskell 在访问时从不需要担心锁数据是共享的。

我认为最大的警告是内存:GHC的垃圾收集器并不是并发的,而且功能风格是分配快乐的。
除此之外,可以编写看起来的程序,就像它们并行一样,但实际上根本不做任何工作,只需要开始和由于懒惰立即返回。一些测试和经验仍然是必要的。但是懒惰和平行并不是不相容的;至少不会,如果你确定你有足够大的“严重”块。强迫严格的事情在很大程度上是微不足道的。

更简单,常见的并行任务(可以用map-reduce方式表示,或者经典的数组向量内容 - 在许多语言中也很容易)通常可以在Haskell中使用并行化的库来更轻松地处理数据结构;其中最着名的是repa

分布式计算

在Cloud Haskell上有相当多的工作,基本上是图书馆形式的Erlang。这种任务不那么直截了当:任何明确的消息发送的想法都有点反对Haskell的粒度,如果语言如此专注于强大的静态类型,那么工作流的许多方面会变得更加麻烦(这是在Haskell,否则往往是一个巨大的奖金,它不仅可以提高安全性和性能,而且还可以更容易编写)。

我认为以分布式并发方式使用Haskell并不遥远,但我们无法说它在该角色中已经成熟。对于分布式并发任务,Erlang本身就是最佳选择。

集群

老实说,Haskell在这里一点都没有帮助你。集群当然原则上是分布式设置的特例,因此可以使用Cloud Haskell;但在实践中,需求是非常不同的。今天的HPC世界(可能还有很长一段时间)取决于MPI,虽然there is a bit of existing work on MPI bindings,我还没有发现它们可用,至少不是就像那样

MPI肯定也非常反对Haskell的粒度,它面向FORTRAN的阵列中心主义,处理类型的奇怪方式等等。但是,除非你坚持使用Haskell的酷炫功能(虽然它通常是所以很诱人!),但是没有理由你也不能在Haskell中编写典型的数字运算代码。唯一的问题是支持/成熟,但这是一个相当大的问题;所以对于集群计算,我建议使用C ++,Python或Julia。

一个有趣的替代方案是从Haskell生成MPI并行化的C或C ++代码。 Paraiso是一个很好的项目。

管道梦想

我经常谈到可以做些什么来使分布式计算在惯用的Haskell中可行。 原则上我相信懒惰可能是一个很大的帮助。我设想的模型是让所有机器独立地计算相同的程序,但是利用Haskell评估通常没有预定顺序的事实。每台机器上的订单都是随机。此外,运行时将跟踪某些计算分支完成的时间,以及结果的大小。如果结果被认为既昂贵又足够紧凑以保证它,那么它将被广播到其他节点,以及一些允许它们快捷计算的合适散列。

这样的系统永远不会像手动优化的MPI应用程序那样高效,但在许多情况下它至少可以提供相同的渐近。它可以轻松处理更复杂的算法。

但是,再一次,这完全是我对不久的将来的模糊希望。

<小时/> 你说并发(关于交互的计算并不是很多),但似乎你的问题是本质上是关于纯计算?