[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.
Cheers,
Morten
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