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

sec*_*rve 4 concurrency multithreading haskell cluster-computing

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

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

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

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

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

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

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

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

Rei*_*chs 8

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

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

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

  4. Haskell(特别是GHC)没有做任何事情来自动并行化评估,因为没有已知的并行化的通用策略,它比非并行化更好.请参阅为什么Haskell中没有隐式并行性?了解更多信息.

  5. 不,见(2).

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

有关Haskell中并行和并发编程的概述,请参阅GHC运行时系统的主要作者Simon Marlow 的同名免费书.


lef*_*out 7

多线程

至于SMP p arallelism 来讲,Haskell是非常有效的.它不是自动,但并行库使得几乎任何东西都很容易并行化.因为火花非常便宜,你可能会非常粗心,只是要求大量的并行性; 然后运行时将知道该怎么做.
与大多数其他语言不同,如果您拥有高度分支的数据结构,棘手的动态算法等,这不是一个大问题 - 由于纯粹的功能范例,并行Haskell 在共享访问数据时从不需要担心锁定.

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

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

分布式计算

在Cloud Haskell上已经有相当多的工作,它基本上是图书馆形式的Erlang.这种任务不那么简单:任何显式消息发送的想法都有点违背Haskell的要求,如果语言如此专注于强大的静态类型(在Haskell中经常使用,那么工作流的许多方面都会变得更加麻烦)一个巨大的奖金,不仅可以提高安全性和性能,还可以更容易编写).

我认为以分布式并发方式使用Haskell并不遥远,但我们不能说它在该角色中已经成熟.对于分布式并发任务,Erlang本身肯定是要走的路.

集群

老实说,Haskell在这里根本不会帮助你.群集当然原则上是分布式设置的特例,因此您可以使用Cloud Haskell; 但在实践中,需求是非常不同的.今天的HPC世界(可能还有很长一段时间)取决于MPI,尽管MPI绑定有一些现有的工作,但我发现它们没有用,至少不是那样.

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

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

管梦

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

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

但同样,这完全是我对不那么近的未来的模糊希望.


你说的是并发性(与计算有关的并不是关于交互),但似乎你的问题本质上是关于纯计算的?