Erlang是否总是在同一节点上的进程之间复制消息?

Mr.*_*. X 11 erlang message-passing

忠实地实现actor消息传递语义意味着消息内容从逻辑视点深度复制,即使对于不可变类型也是如此.消息内容的深度复制仍然是实现actor模型的瓶颈,因此对于性能,一些实现支持零拷贝消息传递(尽管它仍然是程序员的观点的深层拷贝).

在Erlang中是否实现零拷贝消息传递?在节点之间显然不能这样实现,但是在同一节点上的进程之间呢?这个问题是相关的.

arc*_*lus 21

我认为你的断言根本不正确 - 深层复制进程间消息不是Erlang的瓶颈,而且使用默认的VM构建/设置,这正是所有Erlang系统正在做的事情.

Erlang进程堆彼此完全分离,并且消息队列位于进程堆中,因此必须复制消息.对于将数据传入和传出ETS表也是如此,因为它们的数据存储在与进程堆分开的单独分配区域中.

但是,有许多共享数据结构.大二进制文件(> 64字节长)通常在节点范围内分配并进行引用计数.Erlang进程只存储对这些二进制文件的引用.这意味着如果您创建一个大型二进制文件并将其发送到另一个进程,那么您只需发送引用.

在进程之间发送数据实际上在分配大小方面比您想象的要差 - 在复制期间不会保留术语内的共享.这意味着如果您仔细构建一个带共享的术语以减少内存消耗,它将在另一个进程中扩展为其非共享大小.您可以在OTP 效率指南中看到一个实际示例.

正如Nikolaus Gradwohl指出的那样,VM有一个实验性的混合堆模式,它允许进程之间的术语共享并启用零拷贝消息传递.根据我的理解,它并不是一个特别有希望的实验 - 它需要额外的锁定,并使现有的流程能够使独立的垃圾收集变得复杂.因此,复制进程间消息不仅不是Erlang系统中的常见瓶颈,而且实际上降低了性能.

  • 是的,-hybrid 和 -shared 模型在非 SMP 虚拟机中是可行的,但是由于 SMP 中的过度锁定和垃圾收集问题,这些模型非常缓慢且难以维护,因此它们被丢弃了。 (2认同)

Nik*_*ohl 7

AFAIK有/是使用-shared或-hybrid模式在erlang中进行零拷贝消息传递的实验性支持.我在2009年阅读了一篇博文,声称它在smp机器上被破坏了,但我不知道目前的状态


rvi*_*ing 7

正如在这里和其他问题中提到的,当前版本的Erlang基本上复制除了较大的二进制文件之外的所有内容.在较早的SMP之前,不可复制但传递引用是可行的.虽然这导致了非常快速的消息传递,但它在实现中产生了其他问题,主要是它使垃圾收集更加困难和复杂的实现.我认为今天传递引用和共享数据可能导致过度锁定和同步,这当然不是一件好事.