Parallelism and Concurrency II

2010-05-21 Thread Daniel Ruoso
Hi,

After lots of debates off-list (specially with BrowserUk), I got to the
following conclusions:

 - Each OS thread runs a cooperative-event-scheduler where coroutines
   might be enqueued.

 - map returns the buffer immediatly and enqueues a coroutine to process
   the data.

 - Explicit parallel markings such as the feed operator, means a new OS 
   thread with its own cooperative scheduler is spawned.

 - Data that is shared between thread is selectively marked that way to 
   make sure they are thread safe.

 - The actor model can be implemented in a different module.

So, a quick summary of how the following code would run is attached:

  my @a := map { cheap_op($_) } == map { expensive_op($_) }, $*IN

The value sharing framework is still to be designed, but it's clear
that forcing actor model for everything was too intrusive, so we allow a
balance of shared state and massage-passing concurrency. This
balance will be implemented by modules.

comments are appreciated.

daniel
attachment: Perl6ThreadingModel.svg

Fwd: Re: Parallelism and Concurrency was Re: Ideas for aObject-Belongs-to-Thread (nntp: message 4 of 20) threading model (nntp: message 20 of 20 -lastone!-) (nntp: message 13 of 20)

2010-05-18 Thread nigelsandever



--- Forwarded message ---
From: nigelsande...@btconnect.com
To: Dave Whipp - d...@whipp.name  
+nntp+browseruk+e66dbbe0cf.dave#whipp.n...@spamgourmet.com

Cc:
Subject: Re: Parallelism and Concurrency was Re: Ideas for  
aObject-Belongs-to-Thread (nntp: message 4 of 20) threading model (nntp:  
message 20 of 20 -lastone!-) (nntp: message 13 of 20)

Date: Mon, 17 May 2010 22:31:45 +0100

On Mon, 17 May 2010 20:33:24 +0100, Dave Whipp - dave_wh...@yahoo.com
+nntp+browseruk+2dcf7cf254.dave_whipp#yahoo@spamgourmet.com wrote:


From that statement, you do not appear to understand the subject matter

of this thread: Perl 6 concurrency model.

Actually, the reason for my post was that I fear that I did understand  
the subject matter of the thread: seems to me that any reasonable  
discussion of perl 6 concurrency should not be too focused on  
pthreads-style threading.


Okay. Now we're at cross-purposes about the heavily overloaded term
threading. Whilst GPUs overload the term threading for their internal
operations, they are for the most part invisible to applications
programmer. And quite different to the 100,000 threads demos in the Go and
Erlang documentation to which I referred. The latter being MIMD
algorithms, and significantly harder to find applications for than, SIMD
algorithms which are commonplace and well understood.

My uses of the terms threading and threads are limited specifically to
MIMD threading of two forms:

Kernel threading: pthreads, Win32/64 threads etc.
User-space threading: green threads; coroutines; goroutines; Actors; etc.

See below for why I've been limiting myself to these two definitions.

OpenCL/Cuda are not exotic $M hardware: they are available (and  
performant) on any PC (or Mac) that is mainstream or above. Millions of  
threads is not a huge number: its one thread per pixel on a 720p video  
frame (and I see no reason, other than performance, not to use Perl6 for  
image processing).


If the discussion is stricly limited abstracting remote procedure calls,  
then I'll back away. But the exclusion of modules that map  
hyper-operators (and feeds, etc.) to OpenCL from the generic concept of  
perl6 concurrency seems rather blinkered.





FWIW, I absolutely agree with you that the mapping between Perl 6
hyper-operators and (GPU-based or otherwise) SIMD instructions is a
natural fit. But, in your post above you said:

Pure SIMD (vectorization) is insufficient for many of these workloads:
programmers really do need to think in terms of threads (most likely
mapped to OpenCL or Cuda under the hood).

By which I took you to mean that in-box SIMD (be it x86/x64 CPU or GPU
SIMD instruction sets) was insufficient for many of the[se] workloads
you were considering. And therefore took you to be suggesting that the
Perl 6 should also be catering for the heterogeneous aspects of OpenCL in
core.

I now realise that you were distinguishing between CPU SIMD instructions
and GPU SIMD instructions. But the real point here is Perl 6 doesn't need
a threading model to use and benefit from using GPU SIMD.

Any bog-standard single-threaded process can benefit from using CUDA or
the homogeneous aspect of OpenCL where available, for SIMD algorithms.
Their use can be entirely transparent to the language semantics for
built-in operations like the hyper-operators. Ideally, the Perl 6 runtime
would implement roles for OpenCl or CUDA for hyper-operations; fall back
to CPU SIMD instructions; ad fall back again to old-fashioned loops if
neither where available. This would all be entirely transparent to the
Perl 6 programmer, just as utilising discrete FPUs was transparent to the
C programmer back in the day. In an ideal world, Perl 6.0.0.0.0 would ship
with just the looping hyper-operator implementation; and it would be down
to users loading in an appropriately named Role that matched the
hardware's capabilities that would then get transparently picked up and
used by the hyper-operations to give them CPU-SIMD or GPU-SIMD as
available. Or perhaps these would become perl6 build-time configuration
options.

The discussion (which originally started outside of this list), was about
MIMD threading--the two categories above--in order to utilise the multiple
*C*PU cores that are now ubiquitous. For this Perl 6 does need to sort out
a threading model.

The guts of the discussion has been kernel threading (and mutable shared
state) is necessary. The perception being that by using user-threading (on
a single core at a time), you avoid the need for and complexities of
locking and synchronisation. And one of the (I believe spurious) arguments
for the use of user-space (MIMD) threading, is that they are lightweight
which allows you to runs thousands of concurrent threads.

And it does. I've done it with Erlang right here on my dirt-cheap Intel
Core2 Quad Q6600 processor. But, no matter how hard you try, you can never
push the CPU utilisation above 25%, because those 100,000 user-threads all
run

Re: Parallelism and Concurrency was Re: Ideas for a (nntp: message (nntp: message 18 of 20) 14 of 20) Object-Belongs-to-Thread threading model

2010-05-18 Thread Daniel Ruoso
Em Dom, 2010-05-16 às 19:34 +0100, nigelsande...@btconnect.com escreveu:
 3) The tough-y: Closed-over variables.
 These are tough because it exposes lexicals to sharing, but they are so  
 natural to use, it is hard to suggest banning their use in concurrent  
 routines.

This is the point I was trying to address, actually. Having *only*
explicitly shared variables makes it very cumbersome to write threaded
code, specially because explicitly shared variables have a lot of
restrictions on what they can be (this is from my experience in Perl 5
and SDL, which was what brought me to the message-passing idea).

 However, interpreters already have to detect closed over variables in  
 order to 'lift' them and extend their lifetimes beyond their natural  
 scope.

Actually, the interpreter might choose to to implement the closed-up
variables by keeping that entire associated scope when it is still
referenced by another value, i.e.:

 { my $a;
   { my $b = 1;
 { $a = sub { $b++ } } }

this would happen by the having every lexical scope holding a reference
to its outer scope, so when a scope in the middle exits, but some
coderef was returned keeping it as its lexical outer, the entire scope
would be kept.

This means two things:

1) the interpreter doesn't need to detect the closed over variables, so
even string eval'ed access to such variables would work (which is, imho,
a good thing)

2) all the values in that lexical scope are also preserved with the
closure, even if they won't be used (which is a bad thing).

 It doesn't seem it would be any harder to lift them to shared  
 variable status, moving them out of the thread-local lexical pads and into  
 the same data-space as process globals and explicitly shared data.

It is still possible to do the detection on the moment of the runtime
lookup, tho...

 My currently favoured mechanism for handling shared data, is via  
 message-passing, but passing references to the shared data, rather than  
 the data itself. This seems to give the reason-ability, compose-ability  
 and controlled access of message passing whilst retaining the efficiency  
 of direct, shared-state mutability.

That was part of my idea too, I wasn't trying to address remote
processes or anything like that, I was considering doing the queues in
shared memory for its efficiency.

 Only the code that declares the shared  
 data, plus any other thread it choses to send a handle to, has any  
 knowledge of, and therefore access to the shared state.

If we can overcome the limitations we have in Perl 5 shared values, I'm
entirely in agreement with the above statement (assuming closed-over
values become shared transparently)

 Effectively, allocating a shared entity returns a handle to the underlying  
 state, and only the holder of that handle can access it. Such handles  
 would be indirect references and only usable from the thread that creates  
 them. When a handle is passed as a message to another thread, it is  
 transformed into a handle usable by the recipient thread during the  
 transfer and the old handle becomes invalid. Attempt to use an old handle  
 after it has been sent result in a runtime exception.

This is exactly what I meant by RemoteValue, RemoteInvocation and
InvocationQueue in my original idea. 

daniel



Re: Parallelism and Concurrency was Re: Ideas for a (nntp: message (nntp: message 18 of 20) 14 of 20) Object-Belongs-to-Thread threading model

2010-05-18 Thread nigelsandever

On Tue, 18 May 2010 11:39:04 +0100, Daniel Ruoso dan...@ruoso.com wrote:


This is the point I was trying to address, actually. Having *only*
explicitly shared variables makes it very cumbersome to write threaded
code, specially because explicitly shared variables have a lot of
restrictions on what they can be (this is from my experience in Perl 5
and SDL, which was what brought me to the message-passing idea).



Well, do not base anything upon the restrictions and limitations of the  
Perl 5 threads/shared modules. They are broken-by-design in so many ways  
that they are not a good reference point. That particular  
restriction--what a :shared var can and cannot hold--is in some cases just  
an arbitrary restriction for no good reason that I can see.


For example: file handles cannot be assigned to :shared vars is totally  
arbitrary. This can be demonstrated in two ways:


1) If you pass the fileno of the filehandle to a thread and have it dup(2)  
a copy, then it can use it concurrently with the originating thread  
without problems--subject to the obvious locking requirements.


2) I've previously hacked the sources to bypass this restrict by adding  
SVt_PVGV to the switch in the following function:



SV *
Perl_sharedsv_find(pTHX_ SV *sv)
{
MAGIC *mg;
if (SvTYPE(sv) = SVt_PVMG) {
switch(SvTYPE(sv)) {
case SVt_PVAV:
case SVt_PVHV:
case SVt_PVGV: // !!!
if ((mg = mg_find(sv, PERL_MAGIC_tied))
 mg-mg_virtual == sharedsv_array_vtbl) {
return ((SV *)mg-mg_ptr);
}
break;
default:
/* This should work for elements as well as they
 * have scalar magic as well as their element magic
 */
if ((mg = mg_find(sv, PERL_MAGIC_shared_scalar))
 mg-mg_virtual == sharedsv_scalar_vtbl) {
return ((SV *)mg-mg_ptr);
}
break;
}
}
/* Just for tidyness of API also handle tie objects */
if (SvROK(sv)  sv_derived_from(sv, threads::shared::tie)) {
return (S_sharedsv_from_obj(aTHX_ sv));
}
return (NULL);
}

And with that one change, sharing file/directory handles in Perl 5 became  
possible and worked.


The problem is, GVs can hold far more than just those handles. And many of  
the glob-modules utilise the other slots in a GV (array/hahs scalaer etc.)  
for storing state and bless them as objects. At that point--when I tried  
the change--the was a conflict between the blessing that Shared.XS uses to  
make sharing working and any other type of blessing. The net result was  
that whilst the change lifted the restriction upon simple globs, it still  
didn't work with many of the most useful glob-based module--IO::Socket::*;  
HTTP::Deamon; etc. I guess that now the sharing of blessed objects has  
been mage possible, I shoudl try the hack again a see if it would allow  
those blessed globs to work.


Anyway, the point is that the limitations and restrictions of the Perl5  
implementation of the iThreads model, should not be considered as  
fundamental problems with with the iThreads model itself. They aren't.


However, interpreters already have to detect closed over variables  
in

order to 'lift' them and extend their lifetimes beyond their natural
scope.


Actually, the interpreter might choose to to implement the closed-up
variables by keeping that entire associated scope when it is still
referenced by another value, i.e.:

 { my $a;
   { my $b = 1;
 { $a = sub { $b++ } } }

this would happen by the having every lexical scope holding a reference
to its outer scope, so when a scope in the middle exits, but some
coderef was returned keeping it as its lexical outer, the entire scope
would be kept.

This means two things:

1) the interpreter doesn't need to detect the closed over variables, so
even string eval'ed access to such variables would work (which is, imho,
a good thing)


You'd have to explain further for me to understand why it is necessary to  
keep whole scopes around:

- in order to make closures accessible from string-eval;
- and why that is desirable?



2) all the values in that lexical scope are also preserved with the
closure, even if they won't be used (which is a bad thing).



Please no! :)

This is essentially the biggest problem with the Perl 5 iThreads  
implementation. It is the *need* (though I have serious doubts that it is  
actually a need even for Perl 5), to CLONE entire scope stacks every time  
you spawn a thread that makes them costly to use. Both because of the time  
it takes to perform the clone at spawn time; and the memory used to keep  
copies of all that stuff that simply isn't wanted; and in many cases isn't  
even accessible. AFAIK going by what I can find about the history of  
iThreads development, this was only done in Perl 5 in order to provide the  
Windows fork emulation.


But as a 

Re: Parallelism and Concurrency was Re: Ideas for a (nntp: message (nntp: message 18 of 20) 14 of 20) Object-Belongs-to-Thread threading model

2010-05-18 Thread nigelsandever

On Tue, 18 May 2010 11:41:08 +0100, Daniel Ruoso dan...@ruoso.com wrote:


Em Dom, 2010-05-16 às 19:34 +0100, nigelsande...@btconnect.com escreveu:

Interoperability with Perl 5 and
is reference counting should not be a high priority in the decision  
making

process for defining the Perl 6 concurrency model.


If we drop that requirement then we can simply go to the
we-can-spawn-as-many-os-threads-as-we-want model..



I do not see that as a requirement. But, I am painfully aware that I am  
playing catchup with all the various versions, flavours and colors of  
Perl6 interpreter. And more importantly, the significance of each of tehm.  
When I recently started following #perl6 I was blown away (and totally  
confused) by all the various flavours that the eval bot responded to.


The funny thing is that I have a serious soft spot for the timelyness of  
reference couting GC. And I recently came across a paper on a new RCGC  
that claimed to address the circular reference problem without resorting  
to weak references or other labour intensive mechanisms; nor a  
stop-the-world GC cycle. I scanned the paper and it was essentially a  
multi-pass coloring scheme, but achived better performaince than most by


a) running locally (to scopes I think) so that it had far fewer arenas to  
scan.
b) Using a invative coloring scheme that meant it was O(N) rather than the  
usual O(N * M)


Most of it went over my head, (as is often the case with aademic papers),  
but it seems real. But I think that is a boat that has long sailed for  
Perl 6?




daniel



Re: Re: Parallelism and Concurrency was Re: Ideas for aObject-Belongs-to-Thread (nntp: message 4 of 20) threading model (nntp: message 20 of 20 -lastone!-) (nntp: message 13 of 20)

2010-05-18 Thread Daniel Ruoso
Em Ter, 2010-05-18 às 12:58 -0700, Alex Elsayed escreveu:
 You are imposing a false dichotomy here. Neither 'green' threads nor kernel
 threads preclude each other. In fact, it can  be convincingly argued that they
 work _best_ when combined. Please look at the GSoC proposal for hybrid
 threading on the Parrot list.

While I agree that there isn't a dichotomy, the point here is more in
the lines of:

 1) Green threads are usually related to the requirement of serialized 
access to data so you can share all data in the thread without 
resorting to locks for every value.

 2) If that requirement is dropped, once only data that is explicitly   
marked as shared can be seen by both threads, the point for green 
threads is moot, since the OS threads are always going to be better 
performant then a manually implemented scheduler.

My original idea was pointing in creating a shared memory space that
would be seen by every green thread in the same os thread, where some
lines would be drawn to allow OS threading with different memory spaces
- message passing would be used to communicate between two different
memory spaces.

But what we might be getting here is at the point where we don't need
green threads at all... I'm still not sure about one point or another,
tho..

daniel



Re: Parallelism and Concurrency was Re: Ideas for aObject-Belongs-to-Thread threading model (nntp: message 20 of 20 -lastone!-)

2010-05-17 Thread Dave Whipp

nigelsande...@btconnect.com wrote:

There are very few algorithms that actually benefit from using even low 
hundreds of threads, let alone thousands. The ability of Erlang (and go 
an IO and many others) to spawn 100,000 threads makes an impressive demo 
for the uninitiated, but finding practical uses of such abilities is 
very hard.


It may be true that there are only a small number of basic algorithms 
that benefit from massive parallelization. The important thing is not 
the number of algorithms: it's the number programs and workloads. Even 
if there was only one parallel algorithm, if that algorithm was needed 
for the majority of parallel workloads then it would be significant.


In fact, though utilizing thousands of threads may be hard, once you get 
to millions of threads then things become interesting again. Physical 
simulations, image processing, search, finance, etc., are all fields 
that exhibit workloads amenable to large scale parallelization. Pure 
SIMD (vectorization) is insufficient for many of these workloads: 
programmers really do need to think in terms of threads (most likely 
mapped to OpenCL or Cuda under the hood).


To use millions of threads you don't focus on what the algorithm is 
doing: you focus on where the data is going. If you move data 
unnecessarily (or fail to move it when it was necessary) then you'll 
burn power and lose performance.


Re: Parallelism and Concurrency was Re: Ideas for aObject-Belongs-to-Thread (nntp: message 4 of 20) threading model (nntp: message 20 of 20 -lastone!-)

2010-05-17 Thread Aaron Sherman
[Note: removed one CCer because the email address was long and complex and
looked like my mail client had hacked up a hairball full of experimental
Perl 6 obfuscation. My apologies if that wasn't actually a mail failure]

On Mon, May 17, 2010 at 3:13 PM, nigelsande...@btconnect.com wrote:


  The important thing is not the number of algorithms: it's the number
 programs and workloads.


 From that statement, you do not appear to understand the subject matter of
 this thread: Perl 6 concurrency model.


That seems a tad more confrontational than was required. It's also arguably
incorrect. Surveying existing software implementations and code bases is not
precluded, simply because we're talking about a new(ish) language.

For CPU-bound processes, there is no benefit in trying to utilise more than
 one thread per core--or hardware thread if your cores have hyper-threading.
 Context switches are expensive, and running hundreds (let alone thousands or
 millions) of threads on 2/4/8/12 core commodity hardware, means that you'll
 spend more time context switching than doing actual work. With the net
 result of less rather than more throughput.


I know that you know what I'm about to say, but I'm going to say it anyway
just so we're standing on the same ground.

When I was in college, I had access to a loosely coupled 20-processor
system. That was considered radical, cutting-edge technology for the fact
that you could treat it like a standard Unix workhorse, and not as some sort
of black-hole of computing power with which you could commune via a
front-end (ala Cray). I then worked for a company that was producing an
order 1k processor system to do the same thing. These were relatively
short-spaced advances in technology.

When a single die shipped, containing 2 cores, I was agape. I'd never
considered that it would happen as soon as it did.

Today we're putting order of 10 cores on a die.

I'm really not all that old, and yet the shockingly high-end supercomputing
platforms of my youth are, more or less, being put on a chip.

Perl pre-6 hit its stride about 5-10 years into its lifespan (mid to late
90s). Perl 6 hasn't even shipped yet, and yet your statements appear to be
selecting modern hardware as its target platform, design wise. I'm not sure
that's entirely (un)wise. Then again, it does simplify the world
tremendously.

I just wanted to get that all out there for thought.

-- 
Aaron Sherman
Email or GTalk: a...@ajs.com
http://www.ajs.com/~ajs


Re: Parallelism and Concurrency was Re: Ideas foraObject-Belongs-to-Thread (nntp: message 4 of 20) threading model (nntp:message 20 of 20 -lastone!-)

2010-05-17 Thread Dave Whipp

nigelsande...@btconnect.com wrote:

 From that statement, you do not appear to understand the subject matter 
of this thread: Perl 6 concurrency model.


If I misunderstood then I apologize: I had thought that the subject was 
the underlying abstractions of parallelism and concurrency that perl6 
language will define in order to enable specific threading modules to be 
provided by implementations. If the subject is specifically contemporary 
[multicore] CPU threading implementations then my comments may not be 
relevant.




For CPU-bound processes [...].

Sure, there are exotica hardware that have thousands of cores, but it 
hardly seems likely that having spent $millions upon such hardware to 
run your massively parallel algorithms to solve problems in realistic 
time frames, that your going to use a dynamic (no-compiled) language to 
write your solutions in.


Any midrange GPU will support millions of thread-launches per second. 
One frame of 720p video has a million pixels, and these days in not 
uncommon to have multiple threads per pixel.


True, using a dynamic programming language for the guts of these threads 
is probably not a good tradeoff today: I'd probably use an 
Inline::OpenCL module initially. But I see no reason that a strongly 
statically typed subset of Perl6 could not be compiled to efficient 
device-code.


To use millions of threads you don't focus on what the algorithm is 
doing: you focus on where the data is going. If you move data 
unnecessarily (or fail to move it when it was necessary) then you'll 
burn power and lose performance.


Sorry, but I've got to call you on this.

Parallelisation (threading) is all about improving performance. And the 
first three rules of performance are: algorithm; algorithm; algorithm. 
Choose the wrong algorithm and you are wasting cycles. Parallelise that 
wrong algorithm, and you're just multiplying the number of cycles you're 
wasting.


I always thought that the first rule of performance optimization is 
measure (i.e. run a profiler). But ignoring that quibble, the reason 
that bad algorithms are bad is (usually) bad data management (either 
unnecessary movement, or unnecessary locking). If you want to understand 
why an algorithm is inefficient then you need to study the data 
accesses, not (just) the processing. A special case of bad data 
movement, that applies even to sequential code, is cache-thrashing.


This is somewhat analagous to ASIC design: at around .13 um processes, 
wire load delays started to dominate gate delays: wires became a 
dominant source of delay for many paths: initially just the longer 
routes, but these days you can't ignore them. This doesn't mean that you 
can completely ignore the logic: it just means that logic optimization 
is taken as a given, and that the real work is in placement and routing.


Similarly, while a bad algorithm is obviously bad, even a good algorithm 
will perform badly (i.e. will waste memory bandwidth and power) if you 
don't have a way to define how the data will move in the implementation 
of that algorithm. If you're not careful then you'll burn more power 
moving data from/to memory than processing it (slightly stale data: 
moving a 32-bit value to local dram may use 1nJ (1 nanojoule); moving 
that same value a millimeter onchip may burn only 10 pJ: similar to the 
energy of a single-precision floating point operation, but that op needs 
2 source operands and must write a destination, each of which requires a 
data movement. You can, of course, ignore these issues if you're just 
managing a handful of IO-bound CPU threads.


Feel free to tell me that perl6 will never be used in scenarios where 
such considerations are important. I'll probably disagree. But I could 
probably be persuaded that the the current type-system has sufficient 
mechanisms (via traits) to define data placement without any new 
features. And therefore the issue can be ignored until someone actually 
attempts to implement OpenCL bindings.



Dave.


Re: Parallelism and Concurrency was Re: Ideas for a Object-Belongs-to-Thread threading model (nntp: message 20 of 20 -last one!-)

2010-05-16 Thread nigelsandever
On Fri, 14 May 2010 17:35:20 +0100, B. Estrade - estr...@gmail.com  
+nntp+browseruk+c4c81fb0fa.estrabd#gmail@spamgourmet.com wrote:



The future is indeed multicore - or, rather, *many-core. What this
means is that however the hardware jockeys have to strap them together
on a single node, we'll be looking at the ability to invoke hundreds
(or thousands) of threads on a single SMP machine.


There are very few algorithms that actually benefit from using even low  
hundreds of threads, let alone thousands. The ability of Erlang (and go an  
IO and many others) to spawn 100,000 threads makes an impressive demo for  
the uninitiated, but finding practical uses of such abilities is very hard.


One example cited is that of gaming software that runs each sprite ina  
separate thread. The claim is that this simplifies code because each  
sprite only has to respond to situations directly applicable to it, rather  
than some common sprite handler having to select which sprite to operate  
upon. But all it does is move the goal posts. You either have to select  
which sprite to send a message to; or send a message to  the sprite  
handler and have it select the sprite to operate upon.


A third technique is to send the message to all the sprites and have then  
decide if it is applicable to them. But it still requires a loop, and you  
then have the communications overhead *100,000 + the context witch costs *  
100,000. The numbers do not add up.



Then, inevitably,
*someone will want to strap these together into a cluster, thus making
message passing an attractive way to glue related threads together
over a network.  Getting back to the availability of many threads on a
single SMP box, issues of data locality and affinity and thread
binding will become of critical importance.


Perhaps surprisingly, these are not the issues they once were. Whilst  
cache misses are horribly expensive, the multi-layered caching in modern  
CPUs combines with deep pipelines, branch prediction, register renaming  
and other features in ways that are beyond the ability of the human mind  
to reason about.


For a whirlwind introduction to the complexities, see the short video here:

http://www.infoq.com/presentations/click-crash-course-modern-hardware

The only way to test the affects is to profile, and most of the research  
into the effects of cache locality tend to be done in isolation of  
real-world application mixes. very few machines, even servers of various  
types, run a single application these days. This is even truer as server  
virtualisation becomes ubiquitous. Mix in a soupçon of virtual server  
load-balancing and trying to code for cache locality becomes almost  
impossible.



These issues are closely
related to the operating system's capabilities and paging policies, but
eventually (hopefully) current, provably beneficial strategies will be
available on most platforms.

Brett



Parallelism and Concurrency was Re: Ideas for a Object-Belongs-to-Thread threading model

2010-05-14 Thread Richard Hainsworth
After reading this thread and S17, I have lots of questions and some 
remarks.


Parallelism and Concurrency could be considered to be two different things.

The hyperoperators and junctions imply, but do not require, parallelism. 
It is left for the implementors to resolve whether a single or multiple 
processor(s) is/are used. Hence, parallelism could be considered to be 
something under the hood of perl6 and not directly specified.


Given that:
- concurrency is a topic of ongoing research
- several models of concurrency have been tried, including two in perl5
- there are a variety of contexts (internet, clouds, multiple cores, etc)
- different operating systems provide different resources

then:
How much needs to be specified and implemented in perl6 so that 
different concurrency models can be implemented in modules to take into 
account the above diversity?


The less, or rather the more abstract, the specification in perl6, the 
less likely perl6 will 'age'.


On 05/12/2010 09:12 PM, Dave Whipp wrote:

Daniel Ruoso wrote:

Hi,

The threading model topic still needs lots of thinking, so I decided to
try out some ideas.

Every concurrency model has its advantages and drawbacks, I've been
wondering about this ideas for a while now and I think I finally have a
sketch. My primary concerns were:

 1 - It can't require locking: Locking is just not scalable;
 2 - It should perform better with lots of cores even if it suffers
 when you have only a few;
 3 - It shouldn't require complicated memory management techniques 
that  will make it difficult to bind native libraries (yes, STM 
is damn  hard);
 4 - It should suport implicit threading and implicit event-based  
 programming (i.e. the feed operator);

 5 - It must be easier to use then Perl 5 shared variables;
 6 - It can't use a Global Interpreter Lock (that already said in 1, 
 but, as this is a widely accepted idea in some other environments,

 I thought it would be better to make it explicit).

The idea I started was that every object has an owner thread, and only
that thread should talk to it, and I ended up with the following,
comments are appreciated:




comments? ideas?




Before discussing the implementation, I think it's worth while stating 
what it is that you are attempting to abstract. For example, is the 
abstraction intended for a mapping down to a GPU (e.g. OpenCL) with a 
hierarchical address space, or is it intended for a multicore CPU with 
linear address space, or is it intended to abstract a LAN, with 
communication via sockets (reliable TCP? unreliable UDP?), or is it 
intended to abstract the internet/cloud? Are you thinking in terms of 
streaming computation where throughput is dominant, or interacting 
agents where latency is the critical metric?


I'm not sure that it makes sense to talk of a single abstraction that 
supports all of those environments. However, there may be bunch of 
abstractions that can be combined in different ways.


object belongs to thread can have two interpretations: one is that 
the  object-thread binding lasts for the life of the object; the other 
is that a client that wishes to use an object must request ownership, 
and wait to be granted (in some scenarios, the granting of ownership 
would require the thread to migrate to the physical processor that 
owns the state). In many cases, we might find that specific 
object-state must live in specific places, but not all of the state 
that is encapsulated by an object lives in the same place.


Often, an object will encapsulate state that is, itself, accessed via 
objects. If a model requires delegated access to owned state to be 
passed through an intermediate object then this may imply significant 
overhead. A better way to think about such scenarios may be that a 
client would request access to a subset of methods -- and thus we have 
role belongs to thread, not object belongs to thread. One could 
imagine that a FIFO object might have a put role and a get role 
that producer/consumer clients would (temporarily) own while using 
(note that granting of ownership may imply arbitration, and later 
forced-revocation if the resource-ownership is not released/extended 
before some timeout expires). It may be wrong to conflate role as a 
unit of reuse with role as an owned window onto a subset of an 
object's methods.


Perl6 has a set of language primitives to support various aspects of 
concurrency. It is indeed interesting to consider how these map ot 
vastly difference computation platforms: OpenCl Vs OpenMP Vs Cloud. It 
deeps a little premature to be defining roles (e.g. RemoteInvocation) 
without defining the mapping of the core operators to these various 
models of computation.



Dave.


Re: Parallelism and Concurrency was Re: Ideas for a Object-Belongs-to-Thread threading model

2010-05-14 Thread Larry Wall
On Fri, May 14, 2010 at 03:48:10PM +0400, Richard Hainsworth wrote:
: After reading this thread and S17, I have lots of questions and some
: remarks.
: 
: Parallelism and Concurrency could be considered to be two different things.
: 
: The hyperoperators and junctions imply, but do not require,
: parallelism. It is left for the implementors to resolve whether a
: single or multiple processor(s) is/are used. Hence, parallelism
: could be considered to be something under the hood of perl6 and not
: directly specified.

Certainly we've put in a number of abstract constructs that, if used by
the programmer, make promises of parallelizability, even if the the
implementation makes no promises about actual parallelization.

: Given that:
: - concurrency is a topic of ongoing research
: - several models of concurrency have been tried, including two in perl5
: - there are a variety of contexts (internet, clouds, multiple cores, etc)
: - different operating systems provide different resources
: 
: then:
: How much needs to be specified and implemented in perl6 so that
: different concurrency models can be implemented in modules to take
: into account the above diversity?
: 
: The less, or rather the more abstract, the specification in perl6,
: the less likely perl6 will 'age'.

Yes, but...

We need to understand the possibilities sufficiently well to provide a
default implementation that most modules can code to, or we'll simply
end up with a mess of incompatible modules.  This goes doubly for the
standard library; if it is written in a way that violates the
constraints of a thread model, it will not be useable under that model.
(See the Perl 5 ecosystem for what happens if you bolt on threading
after the fact.)

So what we're primarily trying to understand and predict is how the
various threading models will constrain us in our normal coding
patterns, and how we can make those constraints as invisible as
possible without either violating them by accident or inducing
unnecessary overhead.  Requiring the programmer to make a few minor
accomodations to achieve this may buy us a lot of non-grief in
the future.

But as you say, this is not a simple problem to solve; our response
should not be to punt this to future generations, but to solve it
as best as we can, and hope we can make some of the hard decisions
right enough to allow future evolution.

I am very glad to see several passionate but mostly-rational
people thrashing this out here; the future is many-core, and none
of us understand the implications of that well enough yet to write
off the topic as a bikeshed, or to wish for the good old days of
single core.  Sure, it should be possible to write a Perl program in
a single-threaded mindset, but while certain popular languages cling
to the past and try to make single-threadedness a feature, Perl is
more about embracing the future and about freeing the programmer from
arbitrary restrictions.  And as Perl 5 OO demonstrated, sometimes
not picking a good default can be just about as damaging as picking
the wrong one.

Note also that the fundamental difficulty with doing threading in
Perl 5 is not the exact model chosen, but rather that the fundamental
underpinnings of locality were (for various historical reasons)
poorly designed/evolved in the first place, so we ended up with far
too much information having to be managed outside of its proper scope,
for many different definitions of scope.

This has been one of the secret sauces of the Perl 6 redesign, to
hang every piece of information on the peg where it belongs, and not
somewhere else.  And that is why threading of *any* kind will work
much better in Perl 6.

Larry


Re: Parallelism and Concurrency was Re: Ideas for a (nntp: message 14 of 20) Object-Belongs-to-Thread threading model

2010-05-14 Thread Daniel Ruoso
Em Sex, 2010-05-14 às 18:13 +0100, nigelsande...@btconnect.com escreveu:
 The point I(we)'ve been trying to make is that once you have a reentrant  
 interpreter, and the ability to spawn one in an OS thread,
 all the other bits can be built on top. But unless you have that ability,  
 whilst the others can be constructed, the cannot make
 use of SMP. Eg. They cannot scale.

Okay, this is an important point... Having a reentrant interpreter is a
given already, The form I tried to implement that in SMOP was by using
CPS.

The idea of using green threads is just to enforce serialized access to
some data in order to avoid locking (locking with the amount of
polymorphism required by Perl 6 is too expensive), and then the regular
threads wouldn't share data between them.

Of course we could try to have the data structures thread-safe, I didn't
try to go that path since I was trying to get Perl 5 interoperability
and therefore used refcount garbage collector.

The other possibility would be to use processor affinity to force
different threads to spawn in the same processor and that way ensure
serialized access to the non-thread-safe data.

daniel



Re: Parallelism and Concurrency was Re: Ideas for a Object-Belongs-to-Thread threading model

2010-05-14 Thread B. Estrade
On Fri, May 14, 2010 at 03:48:10PM +0400, Richard Hainsworth wrote:
 After reading this thread and S17, I have lots of questions and some 
 remarks.
 
 Parallelism and Concurrency could be considered to be two different things.
 
 The hyperoperators and junctions imply, but do not require, parallelism. 
 It is left for the implementors to resolve whether a single or multiple 
 processor(s) is/are used. Hence, parallelism could be considered to be 
 something under the hood of perl6 and not directly specified.
 
 Given that:
 - concurrency is a topic of ongoing research
 - several models of concurrency have been tried, including two in perl5
 - there are a variety of contexts (internet, clouds, multiple cores, etc)
 - different operating systems provide different resources
 
 then:
 How much needs to be specified and implemented in perl6 so that 
 different concurrency models can be implemented in modules to take into 
 account the above diversity?
 
 The less, or rather the more abstract, the specification in perl6, the 
 less likely perl6 will 'age'.

I might be over simplifying this, but you're going to be building on
essentially 2 different underlying approaches - one is message
passing. The second is threading - I mean *real* threading.  If these
basic facilities are provided in the base, or even via a couple of
robust and tightly integrated modules, then I believe any other scheme
one wishes to implement (even a hybrid scheme), could be done so -
thus solidifying Perl 6's ability to implement the parallel scheme de
jour.

Brett

 On 05/12/2010 09:12 PM, Dave Whipp wrote:
 Daniel Ruoso wrote:
 Hi,
 
 The threading model topic still needs lots of thinking, so I decided to
 try out some ideas.
 
 Every concurrency model has its advantages and drawbacks, I've been
 wondering about this ideas for a while now and I think I finally have a
 sketch. My primary concerns were:
 
  1 - It can't require locking: Locking is just not scalable;
  2 - It should perform better with lots of cores even if it suffers
  when you have only a few;
  3 - It shouldn't require complicated memory management techniques 
 that  will make it difficult to bind native libraries (yes, STM 
 is damn  hard);
  4 - It should suport implicit threading and implicit event-based  
  programming (i.e. the feed operator);
  5 - It must be easier to use then Perl 5 shared variables;
  6 - It can't use a Global Interpreter Lock (that already said in 1, 
  but, as this is a widely accepted idea in some other environments,
  I thought it would be better to make it explicit).
 
 The idea I started was that every object has an owner thread, and only
 that thread should talk to it, and I ended up with the following,
 comments are appreciated:
 
 
 comments? ideas?
 
 
 
 Before discussing the implementation, I think it's worth while stating 
 what it is that you are attempting to abstract. For example, is the 
 abstraction intended for a mapping down to a GPU (e.g. OpenCL) with a 
 hierarchical address space, or is it intended for a multicore CPU with 
 linear address space, or is it intended to abstract a LAN, with 
 communication via sockets (reliable TCP? unreliable UDP?), or is it 
 intended to abstract the internet/cloud? Are you thinking in terms of 
 streaming computation where throughput is dominant, or interacting 
 agents where latency is the critical metric?
 
 I'm not sure that it makes sense to talk of a single abstraction that 
 supports all of those environments. However, there may be bunch of 
 abstractions that can be combined in different ways.
 
 object belongs to thread can have two interpretations: one is that 
 the  object-thread binding lasts for the life of the object; the other 
 is that a client that wishes to use an object must request ownership, 
 and wait to be granted (in some scenarios, the granting of ownership 
 would require the thread to migrate to the physical processor that 
 owns the state). In many cases, we might find that specific 
 object-state must live in specific places, but not all of the state 
 that is encapsulated by an object lives in the same place.
 
 Often, an object will encapsulate state that is, itself, accessed via 
 objects. If a model requires delegated access to owned state to be 
 passed through an intermediate object then this may imply significant 
 overhead. A better way to think about such scenarios may be that a 
 client would request access to a subset of methods -- and thus we have 
 role belongs to thread, not object belongs to thread. One could 
 imagine that a FIFO object might have a put role and a get role 
 that producer/consumer clients would (temporarily) own while using 
 (note that granting of ownership may imply arbitration, and later 
 forced-revocation if the resource-ownership is not released/extended 
 before some timeout expires). It may be wrong to conflate role as a 
 unit of reuse with role as an owned window onto a subset of an 
 object's

Re: Parallelism and Concurrency was Re: Ideas for a Object-Belongs-to-Thread threading model

2010-05-14 Thread B. Estrade
On Fri, May 14, 2010 at 09:50:21AM -0700, Larry Wall wrote:
 On Fri, May 14, 2010 at 03:48:10PM +0400, Richard Hainsworth wrote:

...snip

 
 But as you say, this is not a simple problem to solve; our response
 should not be to punt this to future generations, but to solve it
 as best as we can, and hope we can make some of the hard decisions
 right enough to allow future evolution.
 
 I am very glad to see several passionate but mostly-rational
 people thrashing this out here; the future is many-core, and none
 of us understand the implications of that well enough yet to write
 off the topic as a bikeshed, or to wish for the good old days of
 single core.  Sure, it should be possible to write a Perl program in
 a single-threaded mindset, but while certain popular languages cling
 to the past and try to make single-threadedness a feature, Perl is
 more about embracing the future and about freeing the programmer from
 arbitrary restrictions.  And as Perl 5 OO demonstrated, sometimes
 not picking a good default can be just about as damaging as picking
 the wrong one.

The future is indeed multicore - or, rather, *many-core. What this
means is that however the hardware jockeys have to strap them together
on a single node, we'll be looking at the ability to invoke hundreds
(or thousands) of threads on a single SMP machine. Then, inevitably,
*someone will want to strap these together into a cluster, thus making
message passing an attractive way to glue related threads together
over a network.  Getting back to the availability of many threads on a
single SMP box, issues of data locality and affinity and thread
binding will become of critical importance. These issues are closely
related to the operating system's capabilities and paging policies, but 
eventually (hopefully) current, provably beneficial strategies will be 
available on most platforms.

Brett

 
 Note also that the fundamental difficulty with doing threading in
 Perl 5 is not the exact model chosen, but rather that the fundamental
 underpinnings of locality were (for various historical reasons)
 poorly designed/evolved in the first place, so we ended up with far
 too much information having to be managed outside of its proper scope,
 for many different definitions of scope.
 
 This has been one of the secret sauces of the Perl 6 redesign, to
 hang every piece of information on the peg where it belongs, and not
 somewhere else.  And that is why threading of *any* kind will work
 much better in Perl 6.
 
 Larry

-- 
B. Estrade estr...@gmail.com


Re: S17-concurrency question

2009-02-16 Thread Daniel Ruoso
Em Seg, 2009-02-16 às 17:28 +1100, Timothy S. Nelson escreveu:
   Say I wanted to write a POP3 server.  I want to receive a username and 
 password from the client.  I want things to be interruptable during this, but 
 it's also impossible to sensibly roll things back like they were before the 
 connection was opened.  Is this possible with the concurrency model you 
 specified?

The things you're describing are from the time when we were assuming STM
(Software Transactional Memory) would be used by every implementation of
Perl 6. Things have changed a bit in the last months, as STM seems a bit
more challenging then it looks at first sight for a language as complex
as Perl 6, specially if you think about lazyness.

OTOH, the problem POE solves is the lack of a good green threads
implementation in perl 5, which I think is not a problem for Perl 6 (I
can say that for sure about SMOP, but I'm pretty sure that is also valid
for parrot).

In that specific area of writing network servers, I've been with a fixed
idea about providing autothreading code, so you can write code that
looks like 'imperative block-wait programming', but is actually 'async
non-blocking programming'. I'll paste my last sketch about it here:


my $io = Net::TCP.listen(:hostlocalhost, :port(1234));
$io does IO::Async[EV];
$io.accepts: - $conn {
   my %headers;
   my $data;
   my $waiting_headers = 1;
   for =$conn - $line {
  if ($line  $waiting_headers) {
 my ($name, $val) = split(/\s*:\s*/, $line);
 $headers{$name} = $val;
  } elsif ($line) {
 $data ~= $line;
  } else {
 $waiting_headers = 0;
  }
   }
   $conn.write(200 OK\n\nSucessfull request\n);
};
EV.loop;


daniel



Re: S17-concurrency question

2009-02-16 Thread Timothy S. Nelson

On Mon, 16 Feb 2009, Daniel Ruoso wrote:


Em Seg, 2009-02-16 às 17:28 +1100, Timothy S. Nelson escreveu:

Say I wanted to write a POP3 server.  I want to receive a username and
password from the client.  I want things to be interruptable during this, but
it's also impossible to sensibly roll things back like they were before the
connection was opened.  Is this possible with the concurrency model you
specified?


The things you're describing are from the time when we were assuming STM
(Software Transactional Memory) would be used by every implementation of
Perl 6. Things have changed a bit in the last months, as STM seems a bit
more challenging then it looks at first sight for a language as complex
as Perl 6, specially if you think about lazyness.

OTOH, the problem POE solves is the lack of a good green threads
implementation in perl 5, which I think is not a problem for Perl 6 (I
can say that for sure about SMOP, but I'm pretty sure that is also valid
for parrot).


	I agree that's what it solves, although it has many other 
capabilities.


	What I guess I'm interested in seeing is a consistent threads 
interface which as much as possible (and it may not always be possible) can be 
used across platforms, whether the backend is OS threads or green threads.



In that specific area of writing network servers, I've been with a fixed
idea about providing autothreading code, so you can write code that


I think you a word out (possibly I've been [playing] with...?)


looks like 'imperative block-wait programming', but is actually 'async
non-blocking programming'. I'll paste my last sketch about it here:


	POE looks like it does something very similar.  It works with any kind 
of event loop, though, not just IO.  I just discovered POE yesterday, so it 
still seems very cool to me; we'll see in another month :).


:)


-
| Name: Tim Nelson | Because the Creator is,|
| E-mail: wayl...@wayland.id.au| I am   |
-

BEGIN GEEK CODE BLOCK
Version 3.12
GCS d+++ s+: a- C++$ U+++$ P+++$ L+++ E- W+ N+ w--- V- 
PE(+) Y+++ PGP-+++ R(+) !tv b++ DI D G+ e++ h! y-

-END GEEK CODE BLOCK-


S17-concurrency question

2009-02-15 Thread Timothy S. Nelson

Hi.  I have a question for the S17-concurrency people.

	Say I wanted to write a POP3 server.  I want to receive a username and 
password from the client.  I want things to be interruptable during this, but 
it's also impossible to sensibly roll things back like they were before the 
connection was opened.  Is this possible with the concurrency model you 
specified?


	I've been looking at POE ( http://search.cpan.org/~rcaputo/POE-1.003/ 
) and have observed that it contains its own simulated concurrency (Sessions, 
he calls them), and is, it seems to me, well-designed for doing external data 
transfer as in POP3.  He uses an event-driven model.


Anyway, I'll be interested to hear about this.

:)


-
| Name: Tim Nelson | Because the Creator is,|
| E-mail: wayl...@wayland.id.au| I am   |
-

BEGIN GEEK CODE BLOCK
Version 3.12
GCS d+++ s+: a- C++$ U+++$ P+++$ L+++ E- W+ N+ w--- V- 
PE(+) Y+++ PGP-+++ R(+) !tv b++ DI D G+ e++ h! y-

-END GEEK CODE BLOCK-



Concurrency

2007-12-06 Thread David Brunton
This last SOTO re-reminded me of what an inveterate fan I am of Perl 6.  Wow.

My question today is about concurrency.  I can imagine how things like IPC 
Mailboxes (e.g. RFC 86) happen in modules.  I can also imagine why Threads 
(e.g. RFC 1) should be in modules- given the obvious dependence on underlying 
OS.  I do see both Cfork and Cwait in S29, but not in STD.pm, which brings 
me to the questions:

* Where will Cfork, Cwait, and possible friends (e.g. Perl 5's 
Copen-with-|) live?
* Is there any expectation of message-passing concurrency functions living 
inside STD.pm?
* How about shared/software-transactional memory?

Hopefully I'm not inadvertently starting any kind of flame-fest about anyone's 
favorite concurrency model here :-D

Best,
David.



  

Never miss a thing.  Make Yahoo your home page. 
http://www.yahoo.com/r/hs

Re: Concurrency

2007-12-06 Thread Moritz Lenz
I'll try to reply as good as possible, but I'm sure others will do better.

David Brunton wrote:
 This last SOTO re-reminded me of what an inveterate fan I am of Perl 6.  Wow.
 
 My question today is about concurrency.  I can imagine how things like IPC 
 Mailboxes 
 (e.g. RFC 86) happen in modules.  I can also imagine why Threads (e.g. RFC 1) 
 should 
 be in modules- given the obvious dependence on underlying OS.
 I do see both Cfork and Cwait in S29, but not in STD.pm, which brings me 
 to
the questions:

There's no need for any keyword to be in STD.pm. STD.pm just defines
the grammar. Syntactically fork will be like just another sub, so it can
safely be handled in the compiler's runtime.

 * Where will Cfork, Cwait, and possible friends (e.g. Perl 5's 
 Copen-with-|) live?

What do you mean by where? The namespace? Or the implementation?

 * Is there any expectation of message-passing concurrency functions living 
 inside STD.pm?

Again it won't be in STD.pm, because it doesn't care about it.
But I think there will be both event based and thread based concurrency
in Perl 6.
Larry Wall usually points to this paper:
http://www.seas.upenn.edu/~lipeng/homepage/unify.html

Something like that, with a perlish interface, will be part of Perl 6's
concurrency model.

 * How about shared/software-transactional memory?

Yes.
Maybe http://svn.pugscode.org/pugs/docs/Perl6/Spec/Concurrency.pod
(still a draft) contains a bit more helpful information.

 Hopefully I'm not inadvertently starting any kind of flame-fest
 about anyone's favorite concurrency model here :-D

Why flame, when we can have all of them at once? ;-)

Moritz
-- 
Moritz Lenz
http://moritz.faui2k3.org/ |  http://perl-6.de/





signature.asc
Description: OpenPGP digital signature


Re: Concurrency: hypothetical variables and atomic blocks

2006-06-02 Thread Jonathan Worthington

Jonathan Scott Duff [EMAIL PROTECTED] wrote:

On Thu, Jun 01, 2006 at 02:22:12PM -0700, Jonathan Lang wrote:

Forgive this ignorant soul; but what is STM?


Software Transaction Memory

Well, Software Transactional Memory if I'm being picky.  :-)  Some info and 
an interesting paper here:-

http://www.cambridge.intel-research.net/~rennals/faststm.html

Jonathan 



Re: Concurrency: hypothetical variables and atomic blocks

2006-06-02 Thread Darren Duncan

At 1:50 PM -0700 6/1/06, Larry Wall wrote:

As for side-effecty ops, many of them can just be a promise to perform
the op later when the transaction is committed, I suspect.


Yes, but it would be important to specify that by the time control is 
returned to whatever invoked the op, that any side effects will have 
been successful as well, or a failure/exception is still thrown. 
What happens in Perl itself and what happens as external side effects 
are tied together from the invoker's point of view as one unit that 
should entirely succeed or entirely fail.  Even if the side-effects 
are put off as late as possible in the transaction, we still need to 
know whether they succeeded or not.


On a related note, if there is some external system used in a 
transaction that can't guarantee a successful rollback on failure, 
then any error returned by the Perl op to its invoker should 
differentiate between whether a failure included a successful 
rollback in the external system, or whether said system is now 
possibly or actually in an inconsistent state, so the invoker knows 
whether or not it should be safe to proceed.  Similarly, if the 
external system can't guarantee successful completion before it 
returns control, the invoker should know that vs when completion is 
guaranteed.


In other words, an invoker of an op should know whether the op is 
ACID compliant in all parts of its operation or not.


-- Darren Duncan


Re: Concurrency: hypothetical variables and atomic blocks

2006-06-01 Thread Ruud H.G. van Tol
Darren Duncan schreef:

 Each time a context (a code block, either a routine or a syntactic
 construct like 'try' is) is entered that is marked 'is atomic', a new
 transaction begins, which as a whole can later be committed or rolled
 back; it implicitly commits if that context is exited normally, and
 it rollsback implicitly if the context exits with a 'fail' and/or due
 to a thrown exception.  (And yes, I see it as being easier to use if
 rollback and fail are generally joined at the hip.)

There are also 'lazy atomic' actions that may not achieve (yet) what
they are supposed to do (maybe the storage of some memory structure to a
disk file). So they sort of 'try' and then sort of 'fail', but they
shouldn't block continuation yet, because they will get another go at it
later on.


 One atomic context can contain another atomic context, so they are
 layered; if an outer layer rolls back, it results in any 'successful'
 inner layers also rolling back, so that everything which happened
 within the outer context has rolled back.

If the 'results' would be (for example) text data written to a logfile,
the 'roll back' could be (1) removal of the written data, or (2)
appending a line about the failure. But writing that last line can of
course also fail.

-- 
Groet, Ruud



Re: Concurrency: hypothetical variables and atomic blocks

2006-06-01 Thread Larry Wall
On Thu, Jun 01, 2006 at 11:52:59AM +1200, Sam Vilain wrote:
: The lock on entry approach will only be for non-threaded interpreters
: that don't know how to do real STM.

The way I see it, the fundamental difference is that with ordinary
locking, you're locking in real time, whereas with STM you potentially
have the ability to virtualize time to see if there's a way to order
the locks in virtual time such that they still make sense.  Then you
just pretend that things happened in that order.

As for side-effecty ops, many of them can just be a promise to perform
the op later when the transaction is committed, I suspect.

Larry


Re: Concurrency: hypothetical variables and atomic blocks

2006-06-01 Thread Jonathan Lang

Larry Wall wrote:

The way I see it, the fundamental difference is that with ordinary
locking, you're locking in real time, whereas with STM you potentially
have the ability to virtualize time to see if there's a way to order
the locks in virtual time such that they still make sense.  Then you
just pretend that things happened in that order.


Forgive this ignorant soul; but what is STM?

--
Jonathan Dataweaver Lang


Re: Concurrency: hypothetical variables and atomic blocks

2006-06-01 Thread Jonathan Scott Duff
On Thu, Jun 01, 2006 at 02:22:12PM -0700, Jonathan Lang wrote:
 Larry Wall wrote:
 The way I see it, the fundamental difference is that with ordinary
 locking, you're locking in real time, whereas with STM you potentially
 have the ability to virtualize time to see if there's a way to order
 the locks in virtual time such that they still make sense.  Then you
 just pretend that things happened in that order.
 
 Forgive this ignorant soul; but what is STM?

Software Transaction Memory

-Scott
-- 
Jonathan Scott Duff
[EMAIL PROTECTED]


Concurrency: hypothetical variables and atomic blocks

2006-05-31 Thread Jonathan Lang

How does an atomic block differ from one in which all variables are
implicitly hypotheticalized?  I'm thinking that a retry exit
statement may be redundant; instead, why not just go with the existing
mechanisms for successful vs. failed block termination, with the minor
modification that when an atomic block fails, the state rolls back?

Also, what can retry_with do that testing the atomic block for
failure can't?

--
Jonathan Dataweaver Lang


Re: Concurrency: hypothetical variables and atomic blocks

2006-05-31 Thread Daniel Hulme
 How does an atomic block differ from one in which all variables are
 implicitly hypotheticalized?
I assume that the atomicness being controlled by some kind of lock on
entry, it also applies to I/O and other side-effecty things that you
can't undo.

-- 
Hats are no worse for being made by ancient hatters, and good butter can
be bought in a shop that has no jazz-band.  -- J.B. Morton (Beachcomber)
P.S. --- Tell  Saunders that he  must not leave cat's  meat on  my desk.
http://surreal.istic.org/ old-fashioned quality within the McQuary limit


pgpztA7bT8kxG.pgp
Description: PGP signature


Re: Concurrency: hypothetical variables and atomic blocks

2006-05-31 Thread Sam Vilain
Jonathan Lang wrote:

How does an atomic block differ from one in which all variables are
implicitly hypotheticalized?  I'm thinking that a retry exit
statement may be redundant; instead, why not just go with the existing
mechanisms for successful vs. failed block termination, with the minor
modification that when an atomic block fails, the state rolls back?
  


State rolling back automatically is the key feature of STM.

However, it can only cover pure perl state; any time that you enter a
function that performs I/O of any kind, then you are forcing bad things
to happen.

With Haskell this is sorted out by making the default pure, and
everything else must be in a Monad.  However we're not into bondage here
so is pure is not default.  Instead we just die and rollback just
before I/O is attempted.  In principle, the compiler could automatically
attach pure traits to all functions and methods that it can prove will
never perform I/O and warn about this at compile time.

It might be possible for clever classes to circumvent this and carefully
call special unsafeIO() methods, and be passed messages about the STM
and hope that they do the right thing.  I don't know that anyone's
explored this area in depth in Perl 6 space.

Also, what can retry_with do that testing the atomic block for
failure can't?


I think the answer lies in the checkpointing references in that
document.  I don't know whether that's akin to a SQL savepoint (ie, a
point mid-transaction that can be rolled back to, without committing the
entire transaction) or more like a continuation that when resumed can
see the atomic changes, and when exiting finally applies them (or rolls
back).  Perhaps someone else will have more of a clue.

Sam.


Re: Concurrency: hypothetical variables and atomic blocks

2006-05-31 Thread Sam Vilain
Daniel Hulme wrote:

How does an atomic block differ from one in which all variables are
implicitly hypotheticalized?


I assume that the atomicness being controlled by some kind of lock on
entry, it also applies to I/O and other side-effecty things that you
can't undo.


The lock on entry approach will only be for non-threaded interpreters
that don't know how to do real STM.

Sam.


Re: Concurrency: hypothetical variables and atomic blocks

2006-05-31 Thread Darren Duncan

At 11:51 AM +1200 6/1/06, Sam Vilain wrote:

I think the answer lies in the checkpointing references in that
document.  I don't know whether that's akin to a SQL savepoint (ie, a
point mid-transaction that can be rolled back to, without committing the
entire transaction) or more like a continuation that when resumed can
see the atomic changes, and when exiting finally applies them (or rolls
back).  Perhaps someone else will have more of a clue.
Sam.


Rather than thinking about save points, it would be better to think 
of the problem in terms of child transactions.  (Note that what I'm 
saying here is simplified to assume there aren't any irreversable 
actions, but it can easily be extended to handle those situations 
too.)


Each time a context (a code block, either a routine or a syntactic 
construct like 'try' is) is entered that is marked 'is atomic', a new 
transaction begins, which as a whole can later be committed or rolled 
back; it implicitly commits if that context is exited normally, and 
it rollsback implicitly if the context exits with a 'fail' and/or due 
to a thrown exception.  (And yes, I see it as being easier to use if 
rollback and fail are generally joined at the hip.)


One atomic context can contain another atomic context, so they are 
layered; if an outer layer rolls back, it results in any 'successful' 
inner layers also rolling back, so that everything which happened 
within the outer context has rolled back.


If we simply have child atomic contexts to implement sub-transactions 
of a parent atomic context / transaction, rather than relying on 
savepoints or whatever, then it is much easier to make reusable or 
movable or recursive code, since the code doesn't have to specify its 
own atomicness differently depending on whether its caller is being 
atomic or not.


Eg, we could have a situation like this:

  sub foo is atomic { ... }

  sub bar is atomic { ... }

  sub baz is atomic { ... }

  sub quux is atomic {
...
foo();
...
try {
  bar();
}
catch {
  baz();
}
...
  }

  quux();

All 4 of the above subroutines are individually atomic and will throw 
an exception / return 'fail' and rollback on failure.  If quux() 
fails or foo() or baz() fail, nothing that either of those 3 
subroutines did will persist.  If bar() fails, but baz() succeeds, 
then only what bar() did has rolled back, and the rest persists when 
quux() returns.


Those are my thoughts concerning transactions.  I haven't 
specifically addressed any matters related to exclusivity of 
resources in the cases of multiple processes or threads, but they can 
easily be added onto what I stated, which is also useful when there 
is just a single process with a single thread.


-- Darren Duncan