[m-rev.] for review: granularity control

Peter Wang wangp at students.csse.unimelb.edu.au
Fri Nov 3 00:18:32 AEDT 2006


On 2006-11-02, Zoltan Somogyi <zs at csse.unimelb.edu.au> wrote:
> For review by Peter Wang.
> 
> Zoltan.
> 
> Add an optional pass that tries to avoid generating too many parallel goals.
> The first transformation implemented by this pass is to transform parallel
> conjunctions into goals of the form
...

> Index: compiler/granularity.m
> ===================================================================
> RCS file: compiler/granularity.m
> diff -N compiler/granularity.m
> --- /dev/null	1 Jan 1970 00:00:00 -0000
> +++ compiler/granularity.m	2 Nov 2006 08:49:15 -0000
...
> +
> +:- pred runtime_granularity_test_in_goal(hlds_goal::in, hlds_goal::out,
> +    bool::in, bool::out, list(pred_proc_id)::in, module_info::in) is det.
> +
> +runtime_granularity_test_in_goal(GoalExpr0 - GoalInfo, GoalExpr - GoalInfo,
> +        !Changed, SCC, ModuleInfo) :-
> +    (
> +        GoalExpr0 = conj(parallel_conj, Goals0),
> +        runtime_granularity_test_in_goals(Goals0, Goals, !Changed, SCC,
> +            ModuleInfo),
> +        module_info_get_globals(ModuleInfo, Globals),
> +        globals.get_target(Globals, Target),
> +        (
> +            Target = target_c,
> +            ModuleName = mercury_std_lib_module_name("private_builtin"),

You can use mercury_private_builtin_module from mdbcomp.prim_data.
Also, it could go in par_builtin.

> +            CalledSCCPredProcIds = goal_list_calls_proc_in_list(Goals, SCC),
> +            (
> +                CalledSCCPredProcIds = [],
> +                GoalExpr = conj(parallel_conj, Goals)
> +            ;
> +                CalledSCCPredProcIds = [_ | _],
> +                ProcName = "evaluate_parallelism_condition",
> +                globals.lookup_int_option(Globals, parallelism_target,
> +                    NumCPUs),
> +                NumCPUsStr = string.int_to_string(NumCPUs),
> +                Code = "SUCCESS_INDICATOR = " ++
> +                    "MR_num_outstanding_contexts_and_sparks > " ++
> +                    NumCPUsStr ++ ";",

This is specific to the low-level backend, but that's not checked in
mercury_compile.m.  Also, I suggest calling a macro to make it easier to
experiment with different heuristics.

> +                Args = [],
> +                ExtraArgs = [],
> +                MaybeRuntimeCond = no,
> +                Features = [],
> +                InstMapDeltaSrc = [],
> +                goal_info_get_context(GoalInfo, Context),
> +                some [!Attributes] (
> +                    !:Attributes = default_attributes(lang_c),
> +                    set_purity(purity_semipure, !Attributes),
> +                    set_may_call_mercury(proc_will_not_call_mercury,
> +                        !Attributes),
> +                    set_terminates(proc_terminates, !Attributes),
> +                    set_may_throw_exception(proc_will_not_throw_exception,
> +                        !Attributes),
> +                    set_may_call_mm_tabled(will_not_call_mm_tabled,
> +                        !Attributes),
> +                    set_may_modify_trail(proc_will_not_modify_trail,
> +                        !Attributes),
> +                    Attributes = !.Attributes
> +                ),
> +                generate_foreign_proc(ModuleName, ProcName, predicate,
> +                    only_mode, detism_semi, purity_semipure, Attributes,
> +                    Args, ExtraArgs, MaybeRuntimeCond, Code, Features,
> +                    InstMapDeltaSrc, ModuleInfo, Context, Cond),

I can't see why the goal would need to be semipure.  It will read from
the environment, but the result won't change due to the value it reads.
Also, the values it will read will be affected by pure code, and will be
dynamically changing due to the load so purity doesn't come into it.

> Index: compiler/notes/compiler_design.html
> ===================================================================
> RCS file: /home/mercury/mercury1/repository/mercury/compiler/notes/compiler_design.html,v
> retrieving revision 1.123
> diff -u -b -r1.123 compiler_design.html
> --- compiler/notes/compiler_design.html	15 Sep 2006 11:14:37 -0000	1.123
> +++ compiler/notes/compiler_design.html	2 Nov 2006 07:22:42 -0000
> @@ -1054,6 +1054,30 @@
>    even the user doesn't, and automatically constructed unification and
>    comparison predicates are often dead as well.
>  
> +<li> elimination of dead procedures (dead_proc_elim.m). Inlining, higher-order
> +  specialization and the elimination of unused args can make procedures dead
> +  even the user doesn't, and automatically constructed unification and
> +  comparison predicates are often dead as well.

even _if_ the user doesn't

> +
> +<li> tupling.m looks for predicates that pass around several arguments,
> +  and modifies the code to pass around a single tuple of these arguments
> +  insteead if this looks like reducing the cost of parameter passing.

instead


> Index: tests/par_conj/par_fib.m
> ===================================================================
> RCS file: tests/par_conj/par_fib.m
> diff -N tests/par_conj/par_fib.m
> --- /dev/null	1 Jan 1970 00:00:00 -0000
> +++ tests/par_conj/par_fib.m	2 Nov 2006 09:07:56 -0000
> @@ -0,0 +1,61 @@
> +% vim: ts=4 sw=4 et ft=mercury
> +
> +:- module par_fib.
> +
> +:- interface.
> +
> +:- import_module io.
> +
> +:- pred main(io::di, io::uo) is cc_multi.
> +
> +:- implementation.
> +
> +:- import_module benchmarking.
> +:- import_module int.
> +:- import_module list.
> +:- import_module require.
> +:- import_module string.
> +
> +main(!IO) :-
> +	perform_trial(35, Res),
> +    io.write_int(Res, !IO),
> +    io.nl(!IO).
> +
> +:- pred perform_trial(int::in, int::out) is cc_multi.
> +
> +perform_trial(N, Res) :-
> +	trial(N, Res, SeqTime, ParTime),
> +    trace [compile_time(flag("show_times")), io(!IO)] (
> +        io.format("fib(%d): sequential %d vs parallel %d\n",
> +            [i(N), i(SeqTime), i(ParTime)], !IO)
> +    ).

It's probably worth mentioning these are user times, not real times.

The rest looks fine.


On a related note, it would be useful to have some syntactic sugar for
manual granularity control.  The following syntax is from &-Prolog, but
we'd go for something else, I suspect.

    Cond => G1 & G2

would expand out to

    (Cond -> G1 & G2 ; G1, G2)

to save the programmer duplicating goals with different connectives.

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