Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Erlang always copy messages between processes on the same node?

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.

like image 221
Mr. X Avatar asked Aug 04 '10 14:08

Mr. X


People also ask

How are messages passed between processes on the same node?

All data in messages between Erlang processes on the same Erlang node is copied in the memory. Moreover refc binaries are shared between Erlang processes on the same Erlang node. So it's much much faster than TCP/IP.

Is sending a message blocking the sender Erlang?

As I already mentioned, message passing in Erlang is a non-blocking operation.

What is an Erlang process?

Erlang processes are lightweight, operate in (memory) isolation from other processes, and are scheduled by Erlang's Virtual Machine (VM). The creation time of process is very low, the memory footprint of a just spawned process is very small, and a single Erlang VM can have millions of processes running.

How do I send a message to Erlang?

Erlang uses the exclamation mark (!) as the operator for sending a message. Example: As I have mentioned before, the shell is nothing more than a process.


2 Answers

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.

like image 63
archaelus Avatar answered Oct 30 '22 14:10

archaelus


AFAIK there was/is experimental support for zero-copy message-passing in erlang using the -shared or -hybrid modell. I read a blog post in 2009 claiming that it's broken on smp machines, but I have no idea about the current status

like image 40
Nikolaus Gradwohl Avatar answered Oct 30 '22 14:10

Nikolaus Gradwohl