Quantcast

why concurrency in the first place?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

why concurrency in the first place?

Karel Van Oudheusden
Hello,


I know this may sound like a naieve question but I would like to have a
thorough answer any way :)
"Why does an (Erlang) programmer have to program his application with
concurrency explicitly in mind?"
I also know (think) that this was the main intention of the Erlang
language.

Isn't it easier (cfr. Haskell) to free the programmer (=designer) from
this burden?  If a programmer has to specify it (as is the case in
Erlang), he will typically overspecify his system (even if the processes
are light weight).

Process spawning and message passing are sources of impureness in
Erlang.  This was a pragmatic choice of the Erlang founders.  Is this
because it is (still) difficult for pure functional compilers to do a
good job on extracting optimal concurrency from an initially pure
functional specification?  Does the Haskell compiler do a good job on
this?

I also want to make the following statement (please give feedback):  "It
is always easier to specify a system without explicit concurrency in
mind."  For example:  programming in Haskell (which is almost similar to
specifying) is done in a concurrency-independent way leaving the
eventual implementation to have any degree of true concurrency,
depending on what the compiler decides is best.

And then a final question:  if the application (or system) that has to
be specified contains a high degree of non-manifest constructs (such as
dynamic event behaviour which Erlang was typically designed for), does
the concurrency extraction of the compiler become an even more difficult
job?  Stated otherwise,  is the presence of non-manifest code a good
reason to have the Erlang programmer explicitly define the concurrency
of the system?
Can Haskell for instance tackle non-manifest code efficiently?  What is
the status of this problem in the research community?

thanx,
Karel.

P.S.
I have looked at the "Erlang/OTP R7 - speed test of new inet driver"
code the last couple of days.  It can be found at:
http://www.erlang.se/r7_inet_speed/index.shtm.  I am relatively new to
Erlang.  I must say that this code is not very readable.  I would
typically choose to use more modules in my code.  And I am very
astonished about the different (light-weight) processes that are spawned
every now and then.  Perhaps somebody could explain to me when it is
interesting (from a specification and implementation point of view) to
use a seperate process to accomplish something.  I have worked with
multi-threaded languages previously, but I would have typically chosen
other kinds of abstractions than the ones made here.  And concluding
from my above remarks, I now think a specification should contain no
concurrency at all.



Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

why concurrency in the first place?

Bjarne Däcker-2

Hello

Karel Van Oudheusden wrote:
>
> I know this may sound like a naieve question but I would like to have a
> thorough answer any way :)
> "Why does an (Erlang) programmer have to program his application with
> concurrency explicitly in mind?"

Because many applications that Erlang is
intended for are concurrent by nature.

If you don't have some concepts for concurrency
then you would have to program some sort of
scheduler as part of the implementation.

Best regards

Bjarne


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

why concurrency in the first place?

Hakan Millroth
In reply to this post by Karel Van Oudheusden
> Isn't it easier (cfr. Haskell) to free the programmer
> (=designer) from this burden?  If a programmer has to
> specify it (as is the case in Erlang), he will typically
> overspecify his system (even if the processes are light weight).

I also thought so 10-15 years ago and so did a lot of otherwise
reasonable people. However, declarative programming is about being able
to control the execution of declarative statements. That is, programs
should have a declarative interpretation but, in addition, you must be
able to control how those statements are executed (e.g. concurrency).

One of the early pioneers of declarative programming, Bob Kowalski,
realized this from the beginning and always argued that Logic
Programming is about both Logic and Control (equally true for Functional
Programming). Unfortunately, many other researchers quickly forgot about
the control aspects and focussed instead on "pure" approaches - to the
effect that academic research in this area has had almost no impact on
real-world programming in the last two decades.

-- Hakan

Hakan Millroth
Nortel Networks / Alteon Websystems
50 Great Oaks Blvd.
San Jose, CA 95119, USA


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

why concurrency in the first place?

Maurice Castro
In reply to this post by Karel Van Oudheusden
> Hello,
>
>
> I know this may sound like a naieve question but I would like to have a
> thorough answer any way :)
> "Why does an (Erlang) programmer have to program his application with
> concurrency explicitly in mind?"
> I also know (think) that this was the main intention of the Erlang
> language.
>
> Isn't it easier (cfr. Haskell) to free the programmer (=designer) from
> this burden?  If a programmer has to specify it (as is the case in
> Erlang), he will typically overspecify his system (even if the processes
> are light weight).

Erlang is primarily a language for expressing soft real-time behaviours.
Desirable features in such a language are explicit expression of concurrent
operations, easily predictable performance, and no surprises for the
programmer.

Programming is the process of communicating, in a structured language,
the intentions of the programmer to a compiler. The compiler then produces
code that hopefully implements these intentions. Many of the translation
steps in the process are flawed. The programmer may not understand the
problem, he may not specify it correctly, or the translated code may
interact in an unexpected way with the system.

The intentions Erlang seeks to model explicitly include parallel operations,
having the compiler work out what can be made parallel in fact seeks to
hide the very thing the language is design to make explicit.

Erlang happens to be a functional language to reduce the number of surprises
for the programmer.

        Maurice Castro


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

why concurrency in the first place?

Ulf Wiger-4
In reply to this post by Karel Van Oudheusden
On Mon, 5 Feb 2001, Karel Van Oudheusden wrote:

>I know this may sound like a naieve question but I would like to
>have a thorough answer any way :) "Why does an (Erlang) programmer
>have to program his application with concurrency explicitly in
>mind?" I also know (think) that this was the main intention of the
>Erlang language.

You bring up an important point.


Here's an example, from the world for which Erlang was designed:


In a telephone switch, a phone call is set up via control signals
on a certain interface. Many calls are set up via the same interface.

A handy model for a call setup activity is to split it into two
parts, normally called the A (originating) and B (terminating) sides.
To make things simple, lets say that we have the following components:

a) signaling control link for A side
b) A side "half-call"
c) B side "half-call"
d) resource management for A side interface
e) resource management for B side interface
f) signaling control link for B side

(We've skipped routing, address analysis, and some other fun stuff)

It's very easy to apply an Erlang process model to (a), (b), (c) and
(f), actually. It nicely depicts the built-in concurrency in the
problem. Modeling the problem as objects which may or may not be
concurrent in the real world does not aid understanding in this case.

Looking into, say, the A side half-call, you will find several
independent state machines. They are not concurrent in one sense, as
their state transitions are tightly coupled, but you can, for example
replace one (protocol) layer 3 FSM with another. As it turns out,
implementing these FSMs as separate processes in Erlang would be a
mistake.

Looking at resource management, (d) and (e), it's natural to view them
as two instances of resource management. In the implementation, they
are probably either one or two processes, depending on various issues
(interface distribution, for example.)


Bottom line?

As we design these systems, we try to tell programmers to structure
their code so that specific use of concurrency constructs is limited
to a small part of the code.

The Erlang model of concurrency helps us tie the problem specification
to a concrete behaviour, while maintaining a very high level of
abstraction.

Since the Erlang programmer is offered a very "clean" programming
environment -- no side effects, no other program poking around in your
variables, etc. -- it's easy to concentrate on specifying the program
logic, instead of worrying about administrative stuff (memory
management, critical sections, and so on.)


Then, you can quite easily map your program logic to a concrete
implementation, using the built-in concurrency and
distribution support. Thus, the step from "abstract" specification to
"concrete" specification is very small.




>Isn't it easier (cfr. Haskell) to free the programmer (=designer)
>from this burden?  If a programmer has to specify it (as is the case
>in Erlang), he will typically overspecify his system (even if the
>processes are light weight).

My experience is this:

If you spend too much time on your abstract model, without tying it
down to a concrete implementation, you will most likely overspecify
the system. If you structure your code reasonably well, you will be
able to change the concurrency model several times along the way
without much impact on the majority of your code; but putting it
together and watching it run will also help you find the logical flaws
in your "pure" code.




>Process spawning and message passing are sources of impureness in
>Erlang.  This was a pragmatic choice of the Erlang founders.  Is
>this because it is (still) difficult for pure functional compilers
>to do a good job on extracting optimal concurrency from an initially
>pure functional specification?  Does the Haskell compiler do a good
>job on this?


Getting the level of concurrency just right in a product such as the
AXD 301, cannot be done by a compiler. I can almost guarantee that you
will not get it right the first, or even second or third, time. You
simply have to work the problem enough to figure out what works best.

(http://www.ericsson.se/datacom/products/wan_core/axd301/index.shtml)




>I also want to make the following statement (please give feedback):  
>"It is always easier to specify a system without explicit
>concurrency in mind."  For example:  programming in Haskell (which
>is almost similar to specifying) is done in a
>concurrency-independent way leaving the eventual implementation to
>have any degree of true concurrency, depending on what the compiler
>decides is best.

At one level of specification (abstract specification), you're right:
explicit concurrency shouldn't enter the picture.

Purely functional languages do very well in this area. But when taking
the abstract model one step further to "concretion" (a terrible word
that I just learned), things tend to get messy if your language
doesn't support explicit concurrency.




>I have looked at the "Erlang/OTP R7 - speed test of new inet driver"
>code the last couple of days.  It can be found at:
>http://www.erlang.se/r7_inet_speed/index.shtm.  I am relatively new
>to Erlang.  I must say that this code is not very readable.  I would
>typically choose to use more modules in my code.  And I am very
>astonished about the different (light-weight) processes that are
>spawned every now and then.

Just to be clear, what you're looking at there is not an abstract
specification, nor a concrete specification -- it's deep-core hacking
of functionality that you normally keep a safe distance away from any
high-level modeling tools.

I believe your point, though, is that the code could be written
differently without loss of performance, but greatly benefiting
readability. You're probably right. Too much industrial product code
is butt-ugly when it could be a thing of beauty (the same thing goes
for my programs.) This is something one has to learn to live with to
some degree. This is how it usually works:

1. You have an idea; you don't know if it will work
2. You slap together a prototype and run it
3. Lo and behold: the idea worked
4. Now you want to make it beautiful...
   -- Sorry, no time -- lots of other problems to attack;
   if it works, don't mess with it.

Once in a while, you actually _do_ get the time to make something
really beautiful. Those are the moments...

/Uffe
--
Ulf Wiger                                    tfn: +46  8 719 81 95
Senior System Architect                      mob: +46 70 519 81 95
Strategic Product & System Management    ATM Multiservice Networks
Data Backbone & Optical Services Division      Ericsson Telecom AB



Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

why concurrency in the first place?

Raimo Niskanen-3
In reply to this post by Karel Van Oudheusden
Karel Van Oudheusden wrote:

> P.S.
> I have looked at the "Erlang/OTP R7 - speed test of new inet driver"
> code the last couple of days.  It can be found at:
> http://www.erlang.se/r7_inet_speed/index.shtm.  I am relatively new to
> Erlang.  I must say that this code is not very readable.  I would
> typically choose to use more modules in my code.  And I am very
> astonished about the different (light-weight) processes that are spawned
> every now and then.  Perhaps somebody could explain to me when it is
> interesting (from a specification and implementation point of view) to
> use a seperate process to accomplish something.  I have worked with
> multi-threaded languages previously, but I would have typically chosen
> other kinds of abstractions than the ones made here.  And concluding
> from my above remarks, I now think a specification should contain no
> concurrency at all.

It was a while now, but I feel I have to defend my code a bit. It is a
quick hack to get some figures, not a programming example.

Two or three modules instead of one might not have hurt, on the other
hand all code in one module gives better overview.

The many spawned processes probably comes from the fact that one of the
things we wanted to see were how the scheduling was affected by the new
inet driver. The new driver removed one intermediate process per socket,
and effects of this might show up if there were many processes owning
sockets executing in the emulator.

So, somewhere in the code, an umbrella process is spawned, that
spawn_links a lot of processes each owning a socket. The purpose of this
umbrella process is that it is linked to all testing (socket owning)
processes, and to see if any testing process fails, it is sufficient to
monitor the umbrella process. It dies when any testing process dies,
which kills all other testing processes.

Another reason of complexity is that to get good measurement values, all
tests should be run in a fresh node, so memory fragmentation effects
becomes repeatable, e.g if the memory becomes fragmented, subsequent
tests should not be affected. Therefore the slave:start_link calls, and
the spawn(Node, ...) calls.

Hope this gives some justification to why the code seems more complex
than necessary.

/ Raimo Niskanen, Ericsson UAB, Erlang/OTP development


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

why concurrency in the first place?

Vlad Dumitrescu-3
In reply to this post by Ulf Wiger-4
Hi

I find this discussion very interesting.

But right now I'd like to ask something about something Ulf said:

From: "Ulf Wiger" <etxuwig>
> Looking into, say, the A side half-call, you will find several
> independent state machines. They are not concurrent in one sense, as
> their state transitions are tightly coupled, but you can, for example
> replace one (protocol) layer 3 FSM with another. As it turns out,
> implementing these FSMs as separate processes in Erlang would be a
> mistake.

Why would it be a mistake? (I can think of some reasons, but I'd like to hear yours... :-)

Is it the tight coupling? Efficiency? A design 'no-no'?

regards,
Vlad




Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

why concurrency in the first place?

Ulf Wiger-4
On Wed, 7 Feb 2001, Vlad Dumitrescu wrote:

>Hi
>
>I find this discussion very interesting.
>
>But right now I'd like to ask something about something Ulf said:
>
>From: "Ulf Wiger" <etxuwig>
>> Looking into, say, the A side half-call, you will find several
>> independent state machines. They are not concurrent in one sense, as
>> their state transitions are tightly coupled, but you can, for example
>> replace one (protocol) layer 3 FSM with another. As it turns out,
>> implementing these FSMs as separate processes in Erlang would be a
>> mistake.
>
>Why would it be a mistake? (I can think of some reasons, but I'd
>like to hear yours... :-)
>
>Is it the tight coupling? Efficiency? A design 'no-no'?

A couple of reasons:

- error handling becomes slightly less straightforward
- efficiency suffers because of extra message passing
- latency is increased due to scheduling delays

/Uffe
--
Ulf Wiger                                    tfn: +46  8 719 81 95
Senior System Architect                      mob: +46 70 519 81 95
Strategic Product & System Management    ATM Multiservice Networks
Data Backbone & Optical Services Division      Ericsson Telecom AB



Loading...