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



现在有很多人对Erlang作为一种在多核上编写并行程序的语言感兴趣。我听说有人认为Erlang的消息传递模型比主流的共享内存模型(如线程)更容易编程。

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

有人知道为什么在IT和HPC世界中,消息传递与共享内存的感知存在如此大的差异吗?是不是由于Erlang和MPI在实现消息传递方面的一些根本差异,使得Erlang风格的消息传递比MPI更容易?还是有其他原因?

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

Erlang基于本地内存、异步消息传递和共享状态的概念,通过使用所有线程都可以访问的某种形式的全局数据库来解决。它是为那些不移动大量数据的应用程序设计的,而且不应该爆炸到需要协调的10万个独立节点。

MPI基于本地内存和消息传递,旨在解决移动数据是域的关键部分的问题。高性能计算在很大程度上是将数据集用于某个问题,并将其拆分为大量计算资源。在消息传递系统中,这是一项相当艰巨的工作,因为必须在考虑平衡的情况下显式地分发数据。从本质上讲,MPI可以被视为对共享内存不可伸缩性的勉强承认。它的目标是分布在10万个或更多处理器上的高性能计算。

Erlang并没有试图实现尽可能高的性能,而是将一个自然并行的问题分解为它的自然线程。与MPI相比,它的设计考虑到了完全不同类型的编程任务。

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

Erlang中的并行性仍然很难实现。我的意思是,你仍然需要弄清楚如何解决你的问题,但与C或C++中的一些MPI库相比,有一些小事情可以减轻这种困难。

首先,由于Erlang的消息传递是一个一流的语言特性,语法糖让它感觉更容易。

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

我认为更多的是可用标准库的健壮性将erlang的消息传递与其他MPI实现区分开来,而不是语言本身的任何特定功能。

HPC中的并发通常意味着处理大量数据。这种并行性被称为数据并行性,使用像OpenMP这样的共享内存方法确实更容易实现,因为操作系统负责任务的调度和放置,如果使用消息传递范式,则必须自己实现。

相比之下,Erlang的设计是为了应对电话系统中遇到的任务并行性,在电话系统中,不同的代码必须同时执行,只有有限的通信量和对容错和恢复的强烈要求。

这种模型与大多数人使用PThreads的目的类似。它适用于像web服务器这样的应用程序,在这些应用程序中,每个请求都可以由不同的线程处理,而HPC应用程序对大量数据执行几乎相同的操作,这些数据也必须在工作人员之间交换。

我认为这与使用MPI和Erlang编程时的心态有关。例如,MPI并没有内置到该语言中,而Erlang内置了对消息传递的支持。另一个可能的原因是仅仅发送/接收消息和将解决方案划分为并发执行单元之间的脱节。

使用Erlang,您必须在函数编程框架中思考,在该框架中,数据实际上从一个函数调用快速传递到另一个函数,而接收是一种活跃的行为,看起来像是语言中的正常构造。这使您能够在实际执行的计算和发送/接收消息的行为之间建立更紧密的联系。

另一方面,使用MPI,您只能考虑实际的消息传递,而不能真正考虑工作的分解。这种思维框架需要在编写解决方案和代码中的消息传递基础设施之间进行某种程度的上下文切换。

讨论可以继续,但普遍的观点是,如果消息传递的结构实际上是建立在你正在使用的编程语言和范式中的,那么与其他"附加"或作为语言的附加组件(以库或扩展的形式)相比,这通常是表达解决方案的更好方式。

有人知道为什么在IT和HPC世界中,消息传递与共享内存的感知存在如此大的差异吗?是不是由于Erlang和MPI在实现消息传递方面的一些根本差异,使得Erlang风格的消息传递比MPI更容易?还是有其他原因?

原因只是并行性与并发性。Erlang是为并发编程而培育的。HPC就是关于并行编程的。这些目标是相关但不同的。

并发编程由于控制流的高度不确定性而变得非常复杂,延迟通常是一个重要的目标。Erlang对不可变数据结构的使用极大地简化了并发编程。

并行编程有更简单的控制流,其目标是最大的总吞吐量,而不是延迟。高效的缓存使用在这里要重要得多,这使得Erlang和不可变数据结构在很大程度上都不合适。在这种情况下,改变共享记忆既容易处理,又明显更好。实际上,缓存一致性为您提供了硬件加速的消息传递。

最后,除了这些技术差异之外,还有一个政治问题。Erlang的人试图利用多核的炒作,假装Erlang与多核无关。特别是,他们正在吹捧强大的可扩展性,因此也必须考虑绝对性能。Erlang可以毫不费力地从一个核心上的较差绝对性能扩展到任意数量的核心上的差绝对性能。正如您所能想象的,这并没有给HPC社区留下深刻印象(但对于许多高度并发的代码来说,这已经足够了)。

关于MPI与OpenMP/UPC:MPI迫使您将问题分割成小块,并负责四处移动数据。使用OpenMP/UPC,"所有的数据都在那里",您只需要取消引用一个指针。MPI的优点是32-512 CPU集群比32-512 CPU单机便宜得多。此外,在设计算法时,MPI的费用是前期的。如果你的系统使用NUMA(所有大型系统都使用NUMA),OpenMP/UPC可以隐藏你在运行时会遇到的延迟——你的程序不会扩展,需要一段时间才能弄清楚原因。

这篇文章实际上很好地解释了这一点,Erlang在我们向四周发送小块数据时是最好的,MPI在更复杂的事情上做得更好。Erlang模型也很容易理解:-)

Erlang与MPI的对比-最终结果和源代码

相关内容

  • 没有找到相关文章

最新更新