[m-rev.] for review: parallel execution mechanism (2/2)

Peter Wang wangp at students.csse.unimelb.edu.au
Thu Sep 21 15:09:13 AEST 2006


On 2006-09-20, Julien Fischer <juliensf at csse.unimelb.edu.au> wrote:
> 
> >+% At the end of each conjunct is a command that checks if all the
> >+% conjuncts of the parallel conjunction have been executed and completed.
> >+% If not, we begin execution of the next conjunct as recorded in the
> >+% spark.  If so, the parallel conjunction is complete.  (In reality it's
> >+% a lot more complicated.)
> 
> Unfortunately the Mercury developers (particularly those who will
> have to maintain this piece of code) need to know about reality -
> how/why is it more complicated?

Due to the all the different cases possible, I think this is best
explained by code and inline comments.  I've changed that paragraph to:

% At the end of each conjunct is a call to an join_and_continue instruction.
% It executes the next parallel conjunct or, if the parallel conjunction is
% finished, causes the code following the parallel conjunction to execute in
% the context that originated the parallel conjunction.  If the originating
% context can't execute the next conjunct and the parallel conjunction isn't
% finished, it must suspend and store its address in the sync term.  When a
% non-originating context later finds that the parallel conjunction _is_
% finished, it will then cause the originating context to resume execution
% at the join point.  Please see the implementation of MR_join_and_continue()
% for the details.

> >+/*
> >+** The run queue and spark queue are protected and signalled with the
> >+** same lock and condition variable.
> >+*/
> >MR_Context              *MR_runqueue_head;
> >MR_Context              *MR_runqueue_tail;
> >+#ifndef MR_HIGHLEVEL_CODE
> >+  MR_Spark              *MR_spark_queue_head;
> >+  MR_Spark              *MR_spark_queue_tail;
> >+#endif
> >#ifdef  MR_THREAD_SAFE
> >  MercuryLock           MR_runqueue_lock;
> >  MercuryCond           MR_runqueue_cond;
> >@@ -59,6 +69,11 @@
> >  static MercuryLock    free_context_list_lock;
> >#endif
> >
> >+int MR_num_idle_engines = 0;
> >+int MR_num_outstanding_contexts_and_sparks = 0;
> 
> 
> Is there any reason why these need to be signed ints?

Not really, but we don't need the full range of integers and it's easier
to do sanity checks on signed ints.

> >-void
> >-MR_init_context(MR_Context *c, const char *id, MR_Generator *gen)
> >+static void
> >+MR_init_context_maybe_generator(MR_Context *c, const char *id,
> >+    MR_Generator *gen)
> >{
> >    c->MR_ctxt_id = id;
> >    c->MR_ctxt_next = NULL;
> >@@ -100,29 +116,29 @@
> >#ifndef MR_HIGHLEVEL_CODE
> >    c->MR_ctxt_succip = MR_ENTRY(MR_do_not_reached);
> >
> >-    if (c->MR_ctxt_detstack_zone != NULL) {
> >-        MR_reset_redzone(c->MR_ctxt_detstack_zone);
> 
> 
> I'm not certain that removing the calls to MR_reset_redzone is the right
> thing to be do here.  (I don't know enough about this code to be able to
> say so for sure.)

I couldn't find a reason for resetting redzones.  They are set up when
the zones are first allocated anyway.

> >Index: runtime/mercury_context.h
> >===================================================================
> >RCS file: 
> >/home/mercury/mercury1/repository/mercury/runtime/mercury_context.h,v
> >retrieving revision 1.30
> >diff -u -r1.30 mercury_context.h
> >--- runtime/mercury_context.h	8 Mar 2006 08:35:38 -0000	1.30
> >+++ runtime/mercury_context.h	10 Sep 2006 13:37:23 -0000
...
> >@@ -162,10 +170,41 @@
> >};
> >
> >/*
> >+** A spark contains just enough information to begin execution of a 
> >parallel
> >+** conjunct.  Sparks are allocated on the heap, and can be stored in a
> >+** context's spark stack, or in the global spark queue.  In the former 
> >case, a
> >+** spark will eventually be executed on the same context (same detstack, 
> >etc.)
> 
> s/on the/by the/

The way I think of it now, at the implementation level, _engines_ do the
executing and they do it in environments called "contexts".  We can say
"context C executes foo" but it's actually a shorthand for "an engine E
executes foo in context C".

So "on the" should be "in the" :-)

> >+** as the code that generated the spark.  In the latter case the spark 
> >can be
> >+** picked up and executed by any idle engine in a different context.
> >+**
> >+** In the current implementation a spark is put on the global spark queue 
> >if,
> >+** at the time a fork instruction is reached, we think the spark has a 
> >chance
> 
> s/at/by/

We make the decision while the fork instruction is executing and not
before, so 'at' seems right.

> >Index: runtime/mercury_wrapper.h
> >===================================================================
> >RCS file: 
> >/home/mercury/mercury1/repository/mercury/runtime/mercury_wrapper.h,v
> >retrieving revision 1.74
> >diff -u -r1.74 mercury_wrapper.h
> >--- runtime/mercury_wrapper.h	7 Aug 2006 06:21:32 -0000	1.74
> >+++ runtime/mercury_wrapper.h	10 Sep 2006 05:45:56 -0000
> >@@ -225,6 +225,15 @@
> >/* heap expansion factor for accurate GC (see mercury_accurate_gc.c) */
> >extern  double		MR_heap_expansion_factor;
> >
> >+/* number of outstanding contexts we can create per thread (soft limit) */
> >+extern	MR_Unsigned	MR_contexts_per_thread;
> 
> Please fix the formatting of that comment, e.g.

I'm just following the conventions for the file.

I followed the rest of your suggestions, thanks.

Peter
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to:       mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions:          mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------



More information about the reviews mailing list