On Mon, Dec 26, 2011 at 08:30:29AM -0500, Daniel Ruoso wrote: > 2011/12/26 Nicholas Clark <[email protected]>: > > On Sun, Dec 25, 2011 at 03:31:36PM -0500, Daniel Ruoso wrote: > >> The point I'm trying to address is the one that in Perl 6 we are going > >> to have a lot of implicit threading constructs, such as: > >> my @a <== grep { foo() } <== map { bar() } <== 1..inf; > > Does Perl 6 mandate a threading model akin to POSIX, were the threads of > > execution all run with shared state, something more like Perl 5 ithreads > > (or I guess a message passing system) where everything is decoupled, or > > "it doesn't mandate anything"? > > It doesn't mandate anything, but I think the general expectation is > that you will be able to read and write to values accessible to the > grep and map closures. On the other hand, write operations can be > pessimized by using a message-passing proxy that will talk with a task > running in the OS thread where the external object lives. If you just
Aha. That's the bit that I wasn't aware of. (And hadn't even thought of) > use the input in map and grep it will work completely parallel, but if > you keep writing to outside values, it will be implicitly synchronized > (but just the access to that value, but the order in which this access > happen is still undefined). That works OK for write-only values, and read-only values, I think. But surely either performance or consistency is going to be impossible if the closures both read and write from the same thing? (eg something *like* a counter that's auto-incremented to provide a unique ID for each item processed, but more complex in that the closure reads from it, does something and then writes back. Or does Perl 6 specify that the auto- threading of grep and map is such that if you "do" side effects, it's your responsibility to lock shared resources to avoid race conditions) > >> What do you think? > > Presumably the Perl 6 compiler is only allowed to implicitly parallelise the > > above construction if it can be sure that foo() and bar() have no side > > effects? > > That is not the case, map and grep will not run in order and it is in > general accepted that such constructs will run asynchronously. So, > while it is not forbidden to have side effects, the user will know > that the result is not guaranteed to have any ordering consistency. Yes. But I'm wondering about what the rules are for side effects that the programmer coded that are fine with things happening one at a time in an arbitrary order, but break when more than one thing happens at once. (The same bugs that become exposed when a "multi threaded" program is run for the first time on a multicore machine) Is it explicit that "the programmer has to assume that grep and map can run the closure *concurrently*", and take responsibility for avoiding the consequences? I'm thinking that this *is* the case, from what you write below: > > Presumably this sort of threading only pays off if the CPU gains from > > using multiple cores more than offset the cost of creating the threads, and > > passing return results back? > > I think the parameters on how the tasks will be spread on different OS > threads is something to be fine-tuned (ghc does that, for instance). How straightforward is it to steal stuff from GHC? In that, Haskell is a functional language, so (my understanding is that) unlike Perl 6, variables don't vary. And knowing that things don't vary will let you make assumptions about what is cheap, and where various trade offs lie. Which may not be the same trade offs that one should make if one is coping with variables and side effects. Or is that not really relevant for this topic? > At this moment, the important thing is to properly declare that as > concurrent tasks (which is what the feed operator does) and have a way > to build the flow of data controlling when to block/unblock each task. Ah OK. > That is why I'm considering the idea of a "blocking buffered stream" > VM primitive (and why this thread is on this list), since basically > this will provide a non-OS way to implement blocking reads and writes, > which will effect how the scheduler chooses which task to run. As I > said in the original post, I think the only way to make it efficient > is doing it in the VM level. Yes, my hunch is that it's going to be hard to do it well at a higher level than the fabric of the VM. But as I'm not intimately familiar with Parrot, reality may well prove me wrong on this. Nicholas Clark _______________________________________________ http://lists.parrot.org/mailman/listinfo/parrot-dev
