[erlang-questions] Re: Shared/Hybrid Heap

Morten Krogh mk@REDACTED
Mon Oct 18 10:31:00 CEST 2010

  Hi Jachym

There is one thing that I probably haven't made clear enough, and it 
will answer all points basically.

Erlang has the loop receive loop process that serializes all access to 
the data.
The equivalent in C is a single byte. The semantics of communicating 
with a single byre is well defined in C.
A C thread communicates with the byte using message passing through the 
memory bus. The byte only allows get and put.
Nothing else makes sense.

The general picture is that you have some units of atomicity and beyond 
that you need to lock, coordinate access etc.

Erlang gives you a higher control of the granularity than C, but nothing 
is fundamentally different. I just object to all the Erlang statements 
about locks, concurrency etc.

If you want to get rid of locks and shared memory, you lose concurrency. 
You can't have both. You can serialize everything. In C, that would be 
one thread. In Erlang,
one process. If you want concurrency, you need smaller blocks of data, 
which then needs to be coordinated.

You can imagine an axis

concurrency ~ locks, deadlocks etc  ~ high performance   in one end.

serialized access ~ no locks ~ single threaded  ~ simple programing 
model    in the other end.

C actually beats Erlang in both ends of the axis (not the programming 
model, of course, Erlang syntax is always simpler).

Erlang's sweet spot is in the middle. It is so easy to package an amount 
of data into a serialized agent with controller logic.

The most concurrent program is not an erlang program, that would be a C 
program (or even lower) with a loop on each core, where all iterations 
of all loops updated the memory in all kinds of ways. Each iteration of 
each loop is a "context switch".

Erlang is of course very convenient. You get a whole "block of bytes" 
with serialized access, and a programming language to control the "gate" 
to the block of bytes.

The hardware manufacturers could make something like Erlang, if they 
wanted to. Chop the memory into blocks, and give each block serialized 
access and a small programmable controller sitting at the gate of that 
block. They would lose performance and concurrency if they did.

It is all the same. The only question is at what granularity you 
serialize your data.

Jachym, I will not go through your points. You can imagine my response. 
It is basically :

One byte in C is the equivalent of one Erlang process. One byte doesn't 
need any controller logic besides get and put, and a guaranteed 
atomicity of get and put.



On 10/17/10 11:46 PM, Jachym Holecek wrote:
> # Morten Krogh 2010-10-17:
>> The problem is of course that a process like this
>> loop(State) ->
>>      receive
>>      {From, get, X} ->
>>           From ! {result, get(X, State)},
>>          loop(State)
>>      etc.....
>> Behaves exactly like shared memory seen from other processes point of view.
>> Writing
>> Pid ! {self(), get, 27}
>> receive
>>      {result, Result} ->
>>          Result
>> end.
>> is like writing
>> get(X, Pid) in C (the language) where Pid is pointer to a shared data
>> structure in C.
> "Apples and oranges" as they say. In your Erlang example:
>    * Server explicitely agrees to provide some of its data.
>    * Server is free to change this decision.
>    * Client has to follow certain protocol to access this data.
>    * All accesses to "shared" data are serialized.
>    * It is "physically impossible" to obtain inconsistent snaphost of the data.
>    * It is "physically impossible" to bypass server's control.
>    * This is guaranteed at language level.
>    * Your example is implemented completely within this well-defined semantics.
> Contrast that with C:
>    * All threads have equal access right to whole process address space.
>    * Sychronization can be done, but is a mere convention (spinlocks/mutexes).
>    * Data consistency can be done, but is a mere convetion (memory barriers).
>    * At language level memory access semantics is more or less undefined.
>    * Mutexes/memory barriers have to be done in assembly, ie. outside C.
> A little more fun on the C side:
>    * Compiler may reorder loads/stores (somewhat) unless you're careful.
>    * CPU may reorder loads/stores (somewhat) unless you're careful.
>    * Cache may do whatever it wants to (somewhat) unless you're careful.
> Normally these thing will be taken care of by whatever threads implementation
> you use (in architecture- and compiler-specific way), but if we're talking at
> language level then there's no way (as far as I know) to achieve sane shared
> memory semantics in C alone (if we admit the existence of concurrent threads
> of execution which the language knows nothing about, of course).
> But sure -- you can _model_ Erlang-like processes in C, and you can _model_
> C-like shared memory in Erlang (including all of the quirks above if you
> really wanted to). But at that point you're imposing correspondence of some
> sort by brute force; as opposed to capturing inherent properties.
> Just my two pence...
> Regards,
> 	-- Jachym
> ________________________________________________________________
> erlang-questions (at) erlang.org mailing list.
> See http://www.erlang.org/faq.html
> To unsubscribe; mailto:erlang-questions-unsubscribe@REDACTED

More information about the erlang-questions mailing list