问题描述
忠实执行actor消息传递语义意味着即使对于不可变类型,消息内容也从逻辑角度深入复制。消息内容的深度复制仍然是执行actor模型的瓶颈,因此,对于性能,一些实现支持零复制消息传递(尽管它仍然是程序员的观点深入复制)。
是否在Erlang中执行零拷贝消息传递?在节点之间,它显然不能像这样实现,但在同一节点上的进程之间呢? 是相关的。 / p>
我不认为你的断言是正确的 - 深入复制过程间消息不是Erlang的瓶颈,并使用默认的VM构建/设置,这正是Erlang系统正在进行的所有操作。
Erlang进程堆是完全独立的,消息队列是位于进程堆中,因此必须复制消息。将数据传入和传出ETS表也是如此,因为它们的数据存储在与进程堆不同的分配区域中。
然而,有许多共享数据结构。大型二进制(> 64字节长)通常分配在节点范围内,并被引用计数。 Erlang进程只是存储对这些二进制文件的引用。这意味着如果您创建一个较大的二进制文件并将其发送到另一个进程,则只会发送引用。
在进程之间发送数据实际上在分配方面更糟大小比你可能想像的 - 在复制期间共享内容不会被保留。这意味着如果您仔细构建一个具有共享的术语来减少内存消耗,那么在另一个进程中它将扩展到其非共享大小。您可以在OTP 中看到一个实际的例子。
$如Nikolaus Gradwohl所指出的那样,VM的实验性混合堆栈模式允许进程之间进行术语共享并启用零拷贝消息传递。根据我的理解,它并不是一个特别有希望的实验 - 它需要额外的锁定,并使现有的过程独立垃圾收集的能力复杂化。因此,不仅复制流程间消息不是Erlang系统中通常的瓶颈,从而实际上降低了性能。A faithful implementation of the actor message-passing semantics means that message contents are deep-copied from a logical point-of-view, even for immutable types. Deep-copying of message contents remains a bottleneck for implementations the actor model, so for performance some implementations support zero-copy message passing (although it's still deep-copy from the programmer's point-of-view).
Is zero-copy message-passing implemented at all in Erlang? Between nodes it obviously can't be implemented as such, but what about between processes on the same node? This question is related.
I don't think your assertion is correct at all - deep copying of inter-process messages isn't a bottleneck in Erlang, and with the default VM build/settings, this is exactly what all Erlang systems are doing.
Erlang process heaps are completely separate from each other, and the message queue is located in the process heap, so messages must be copied. This is also true for transferring data into and out of ETS tables as their data is stored in a separate allocation area from process heaps.
There are a number of shared datastructures however. Large binaries (>64 bytes long) are generally allocated in a node-wide area and are reference counted. Erlang processes just store references to these binaries. This means that if you create a large binary and send it to another process, you're only sending the reference.
Sending data between processes is actually worse in terms of allocation size than you might imagine - sharing inside a term isn't preserved during the copy. This means that if you carefully construct a term with sharing to reduce memory consumption, it will expand to its unshared size in the other process. You can see a practical example in the OTP Efficiency Guide.
As Nikolaus Gradwohl pointed out, there was an experimental hybrid heap mode for the VM which did allow term sharing between processes and enabled zero-copy message passing. It hasn't been a particularly promising experiment as I understand it - it requires extra locking and complicates the existing ability of processes to independently garbage collect. So not only is copying inter-process messages not the usual bottleneck in Erlang systems, allowing it actually reduced performance.
这篇关于Erlang是否总是在同一个节点上的进程之间复制消息?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!