为什么MPI被认为比共享内存更难,而Erlang被认为更容易,尽管它们都是消息传递?

34

最近有很多人对Erlang语言作为用于在多核上编写并行程序的语言表现出浓厚的兴趣。有人认为,与线程等主流共享内存模型相比,Erlang的消息传递模型更容易编程。

相反,在高性能计算领域,主导的并行编程模型是MPI,它也实现了消息传递模型。但在HPC世界中,这种消息传递模型通常被认为非常难以编程,人们认为OpenMP或UPC等共享内存模型更容易编程。

是否有人知道IT和HPC世界中消息传递和共享内存的看法差异如此之大的原因?是由于Erlang和MPI实现消息传递的基本差异使得Erlang风格的消息传递比MPI容易得多?还是有其他原因?


我发现相反,MPI和Erlang比共享内存更容易! - pyCthon
7个回答

39

我同意之前的所有答案,但我认为一个并非完全清晰的关键点是 MPI 可能被认为很难而 Erlang 很容易的原因之一是模型与域的匹配。

Erlang 基于本地内存、异步消息传递和使用某种形式的全局数据库来解决共享状态问题,所有线程都可以访问。它专为不需要大量数据移动且不会扩展到需要协调的 100k 个单独节点的应用程序而设计。

MPI 基于本地内存和消息传递,旨在解决数据移动是域的关键部分的问题。高性能计算非常注重将问题的数据集拆分成众多计算资源的部分。在消息传递系统中进行这项工作非常困难,因为数据必须明确分布并考虑平衡问题。从本质上讲,MPI 可以看作是共享内存不可扩展的勉强承认,并且其目标是分布在 10 万个处理器或更多的高性能计算。

Erlang 并不试图实现最高可能的性能,而是将自然并行问题分解为其自然的线程。与 MPI 相比,Erlang 的设计思路完全不同类型的编程任务。

因此,Erlang 最好与 pthreads 和其他相当本地异构线程解决方案进行比较,而不是 MPI,后者真正针对非常不同(在某种程度上具有固有的难度)的问题集。


13

Erlang的并行性实现仍然相当困难。我的意思是,你仍然需要想出如何分割你的问题,但与C或C ++中的某些MPI库相比,有一些小细节可以缓解这种困难。

首先,由于Erlang的消息传递是一种一流的语言特性,所以它的语法糖使其感觉更容易。

此外,Erlang库都是围绕Erlang消息传递构建的。这种支持结构有助于让你进入并行处理领域。看看OTP的组件,如gen_server、gen_fsm、gen_event。这些都是非常易于使用的结构,可以帮助你的程序变得并行。

我认为,可用标准库的健壮性更多地区别于erlang的消息传递和其他MPI实现,而不是语言本身的任何特定特征。


10

通常在高性能计算中,并发性意味着处理大量数据。这种并行性称为数据并行,使用像OpenMP这样的共享内存方法实现确实更容易,因为操作系统会处理调度和任务分配等事项,如果使用消息传递模式,则需要自己实现这些。

相比之下,Erlang是为电话系统中遇到的任务并行而设计的,在这种情况下,不同的代码片段必须以仅有限的通信和强烈的容错和恢复要求并发执行。

这种模型类似于大多数人使用PThreads的方式。它适合像Web服务器这样的应用程序,其中每个请求可以由不同的线程处理,而HPC应用程序则在大量数据上执行完全相同的操作,这些数据还必须在工作进程之间交换。


9
我认为使用MPI编程和使用Erlang编程时,思维方式有所不同。例如,MPI没有内置语言支持,而Erlang具有内置的消息传递支持。另一个可能的原因是仅发送/接收消息与将解决方案分成并发执行单元之间的断开。
在Erlang中,您被迫以函数式编程框架思考,其中数据实际上从函数调用到函数调用快速传递——接收是一种主动行为,看起来像语言中的正常结构。这使您更紧密地连接了实际执行的计算和发送/接收消息的行为。
另一方面,在MPI中,您只需考虑实际的消息传递,而不是真正的工作分解。这种思考框架需要在编写解决方案和代码中的消息基础设施之间进行某种上下文切换。
讨论可以继续进行,但通常的观点是,如果消息传递的结构实际上内置于您正在使用的编程语言和范例中,那么通常这是表达解决方案的更好方法,而不是其他作为语言的附加组件存在(以库或扩展的形式)。

5
有人知道为什么在IT和HPC领域中,消息传递和共享内存的感知存在如此大的差异吗?是因为Erlang和MPI实现消息传递的根本差异使得Erlang风格的消息传递比MPI容易得多呢?还是有其他原因?
原因很简单,就是并发与并行。Erlang适用于并发编程,而HPC则是关于并行编程。这些目标相关但不同。
并发编程由于控制流非常不确定且延迟通常是一个重要目标,所以变得非常复杂。Erlang使用不可变数据结构大大简化了并发编程。
并行编程具有更简单的控制流,并且目标是最大总吞吐量而不是延迟。在这里,高效的缓存使用更加重要,这使得Erlang和不可变数据结构都不太合适。在这种情况下,改变共享内存既可处理,也显著更好。实际上,缓存一致性为您提供了硬件加速的消息传递。
最后,除了这些技术差异之外,还存在政治问题。Erlang的开发者试图通过假装Erlang与多核相关来跟风多核热潮。特别是,他们宣传出色的可伸缩性,因此必须考虑绝对性能。Erlang从一个核上的低绝对性能轻松扩展到任意数量的核上的低绝对性能。你可以想象,这并没有给HPC社区留下深刻印象(但对于许多高度并发的代码来说是足够的)。

1
关于MPI与OpenMP/UPC:MPI强制你将问题切分成小块,并负责数据的移动。而使用OpenMP/UPC,“所有数据都在那里”,你只需要解引用一个指针即可。MPI的优势在于32-512个CPU集群比32-512个CPU单机要便宜得多。此外,使用MPI时,开销是预先计算好的,在设计算法时就已经考虑到了。如果你的系统使用NUMA(所有大型系统都会使用),OpenMP/UPC可以隐藏运行时可能出现的延迟,但你的程序不会扩展,并且需要一段时间才能找出原因。

我理解这个论点,但为什么它不适用于Erlang vs. OpenMP呢?你在Erlang中仍然需要切分问题吧? - Lorin Hochstein

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接