This should be a reply to Daniel Ruoso's post above, but I cannot persuade
my nntp reader
to reply to a post made before I subscribed here. Sorry
On Wed, 12 May 2010 14:16:35 +0100, Daniel Ruoso wrote:
I have 3 main problems with your thinking.
1: You are conflating two fundamentally different views of the problem.
a) The Perl 6 programmers semantic view.
b) The P6 compiler (writers) implementation view.
These two views need to be kept cleanly separated in order that reference
implementation does not define the *only possible* implementation.
But, it is important that when designing the semantic view, that it is done
with a considerable regard for what /can/ be implemented.
2: You appear to be taking your references at face value.
For example, you've cited Erlang as one of your reference points.
And the Erlang docs describe the units of concurrency as "processes";
with "the parallelism is provided by Erlang and not the host operating
system."
But, if I run one of the Erlang examples,
http://www.erlang.org/examples/small_examples/tetris.erl
it uses two procesess: one with 13 OS threads, and the other with 5 OS
threads;
even if I only run tetris:start(1).
Whilst until recently, Erlang did not use OS threads, relying instead upon
and internal, user-space scheduler--green threading, though you may find
some denials
of that by Erlangers because of the unfavorable comparison with Java green
threading
in Java version 1 thru 4.
But recent versions have implemented multiple OS trheads each running a
coroutine scheduler.
The had to do this in order to achieve SMP scaling. Here is a little
salient information:
"The Erlang VM without SMP support has 1 scheduler which runs in the
main process thread. The scheduler picks runnable Erlang processes and
IO-jobs from the run-queue and there is no need to lock data structures
since
there is only one thread accessing them.
The Erlang VM with SMP support can have 1 to many schedulers which are
run in 1 thread each. The schedulers pick runnable Erlang processes
and IO-jobs from one common run-queue. In the SMP VM all shared data
structures are protected with locks, the run-queue is one example of a
data structure protected with locks."
Lock-free at the semantic level is a nice-to-have. But, whenever you have
kernel threads
talking to each other through shared memory--and you have to have if you
are going to achieve
SMP scalability--then there will be some form of locking required.
All talk of "message passing protocols" is simply disguising the realities
of the implementation.
That is not a bad thing from the applications programmer's point of
view--nor even the language
designer's POV--but it still leaves the problem to be dealt with by the
language & system implementers.
Whilst lock-free queues are possible--there are implementations of these
available for Java 5
(which, of necessity, and to great effect, has now moved away from green
threads and gone the
Kernel threading route.)--they are very, very hardware dependant. Relying
as they do upon CAS, which
not all processor architectures support and not all languages give
adequate access to.
For a very interesting, if rather long, insight into some of this, see
Cliff Click's video about
"Fast Wait-free Hashtables":
http://www.youtube.com/watch?v=WYXgtXWejRM&feature=player_embedded#!
One thing to note if you watch it all the way through is that your claim
(in an earlier revision?)
that "shared memory doesn't scale" is incorrect in the light of this video
where 786 SMP processors
are using a hash for caching at very high speed.
3: By conflating the POVs of the sematic design and implementation, you
are in danger of reinventing
several bad wheels, badly.
a) A green threading scheduler:
The Java guys spent a long time trying to get their's right before
abandoning it.
The Erlang guys have taken a long time tuning their's, but due to Moore's
Law running out,
they have had to bow to the inevitability of kernel threading. And are
now having to go
through the pain of understanding and addressing how multiple event
driven and cooperative
schedulers running under the control of (various) preemptive scheduler(s)
interact.
Even Haskell has to use kernel threading:
"In GHC, threads created by forkIO are lightweight threads, and are
managed entirely by the
GHC runtime. Typically Haskell threads are an order of magnitude or two
more efficient
(in terms of both time and space) than operating system threads.
The downside of having lightweight threads is that only one can run at a
time, so if one thread
blocks in a foreign call, for example, the other threads cannot continue.
The GHC runtime works
around this by making use of full OS threads where necessary. When the
program is built with the
-threaded option (to link against the multithrea