[m-rev.] for review: new module mdprof_CSS_above_threshold

Julien Fischer juliensf at csse.unimelb.edu.au
Thu Oct 19 14:59:13 AEST 2006


On Thu, 19 Oct 2006, Jerome Tannier wrote:

> Branches: main
>
> deep_profiler/mpdrof_feedback.m:
>    New module which writes to a file the list of call sites static
>    whose matching call sites dynamic's average/median
>    callseqs exceed the given threshold.
>
> Mmakefile:
> deep_profiler/Mmakefile:
>    Build and install mdprof_feedback.m.
>
>    Fix an existing bug. The install target should depend
>    on mdprof_test and mdprof_dump.
>

...

> Index: deep_profiler/mdprof_feedback.m
> ===================================================================
> RCS file: deep_profiler/mdprof_feedback.m
> diff -N deep_profiler/mdprof_feedback.m
> --- /dev/null	1 Jan 1970 00:00:00 -0000
> +++ deep_profiler/mdprof_feedback.m	19 Oct 2006 01:46:27 -0000
> @@ -0,0 +1,322 @@
> +%-----------------------------------------------------------------------------%
> +% vim: ft=mercury ts=4 sw=4 et
> +%-----------------------------------------------------------------------------%
> +% Copyright (C) 2001, 2004-2006 The University of Melbourne.

The dates there are incorrect.

> +% This file may only be copied under the terms of the GNU General
> +% Public License - see the file COPYING in the Mercury distribution.
> +%-----------------------------------------------------------------------------%
> +%
> +% File: mdprof_feedback.m.
> +% Author: tannier.
> +%
> +% This module contains the code for writing to a file the CSSs whose
> CSD's
> +% average/median callseqs (own and desc) exceed the given threshold.
> +%
> +% The generated file will then be used by the compiler for implicit
> parallelism.
> +%
> +%-----------------------------------------------------------------------------%
> +
> +:- module mdprof_feedback.
> +:- interface.
> +
> +:- import_module io.
> +
> +%-----------------------------------------------------------------------------%
> +
> +:- pred main(io::di, io::uo) is det.
> +

...

> +
> +main(!IO) :-
> +    io.progname_base("Profiling feedback program", ProgName, !IO),

s/Profiling feedback program/mdprof_feedback/

> +    io.command_line_arguments(Args0, !IO),
> +    getopt.process_options(option_ops_multi(short, long, defaults),
> +        Args0, Args, MaybeOptions),
> +    (
> +        MaybeOptions = ok(Options),
> +        lookup_bool_option(Options, help, Help),
> +        lookup_bool_option(Options, version, Version),
> +        ( Version = yes ->
> +            io.format("%s Version 1.0\n", [s(ProgName)], !IO)

The version number should not be hardcoded as 1.0 there.  For
consistency with the rest of the the Mercury tools the version "number"
should the string returned by predicate library.version/1.

> +        ; Help = yes ->
> +            write_help_message(ProgName, !IO)
> +        ;
> +            ( Args = [Input, Output] ->
> +                lookup_string_option(Options, distribution,
> Distribution),
> +                ( construct_distribution(Distribution,
> DistributionType) ->
> +                    lookup_int_option(Options, threshold, Threshold),
> +                    lookup_bool_option(Options, verbose, Verbose),
> +                    read_deep_file(Input, Verbose, MaybeProfile, !IO),
> +                    (
> +                        MaybeProfile = ok(Deep),
> +                        compute_css_list_above_threshold(0, Deep,
> Threshold,
> +                            DistributionType, [],
> CSSListAboveThreshold),
> +                        generate_file(CSSListAboveThreshold, Deep,
> +                            DistributionType, Threshold, Output, !IO)
> +                    ;
> +                        MaybeProfile = error(Error),
> +                        io.stderr_stream(Stderr, !IO),
> +                        io.set_exit_status(1, !IO),
> +                        io.format(Stderr, "%s: error reading deep file:
> %s\n",
> +                            [s(ProgName), s(Error)], !IO)
> +                    )
> +                ;
> +                    io.set_exit_status(1, !IO),
> +                    write_help_message(ProgName, !IO)
> +                )
> +            ;
> +                io.set_exit_status(1, !IO),
> +                write_help_message(ProgName, !IO)
> +            )
> +        )
> +    ;
> +        MaybeOptions = error(Msg),
> +        io.stderr_stream(Stderr, !IO),
> +        io.set_exit_status(1, !IO),
> +        io.format(Stderr, "%s: error parsing options: %s\n",
> +            [s(ProgName), s(Msg)], !IO)
> +    ).
> +
> +:- pred write_help_message(string::in, io::di, io::uo) is det.
> +
> +write_help_message(ProgName) -->
> +    io.format("Usage: %s [<options>] <input> <output>\n",
> [s(ProgName)]),
> +    io.format("<input> must name a deep profiling data file.\n", []),
> +    io.format("<output> is the file generated by this program.\n", []),
> +    io.format("You may specify one of the following options:\n", []),
> +    io.format("--help      Generate this help message.\n", []),
> +    io.format("--version   Report the program's version number.\n",
> []),
> +    io.format("--verbose   Generate progress messages.\n", []),
> +    io.format("--threshold <value>\n", []),
> +    io.format("            Set the threshold to <value>.\n",[]),
> +    io.format("--distrib average|median\n",[]),
> +    io.format("            average : Write to <output> the call sites
> \n",[]),
> +    io.format("            static whose call sites dynamic's average
> \n",[]),
> +    io.format("            callseqs exceed the given threshold (default

For the documentation it would be clearer to write
"call sequence counts", rather than "callseqs".  Also below.

> \n",[]),
> +    io.format("            option).\n",[]),
> +    io.format("            median : Write to <output> the call sites
> \n",[]),
> +    io.format("            static whose call sites dynamic's median
> \n",[]),
> +    io.format("            callseqs exceed the given threshold.\n",[]).
> +
> +%-----------------------------------------------------------------------------%
> +
> +    % Reads a deep data file.
> +    %

I suggest:

 	Read a deep profiling data file.

> +:- pred read_deep_file(string::in, bool::in, maybe_error(deep)::out,
> +    io::di, io::uo) is det.
> +
> +read_deep_file(Input, Verbose, MaybeProfile, !IO) :-
> +    server_name(Machine, !IO),
> +    (
> +        Verbose = yes,
> +        io.stdout_stream(Stdout, !IO),
> +        MaybeOutput = yes(Stdout)
> +    ;
> +        Verbose = no,
> +        MaybeOutput = no
> +    ),
> +    read_and_startup(Machine, [Input], no, MaybeOutput, [], [],
> MaybeProfile,
> +        !IO).
> +
> +    % Determines those CSSs whose CSDs have an average/median callseq
> count
> +    % above the given threshold.
> +    %
> +:- pred compute_css_list_above_threshold(int::in, deep::in, int::in,
> +    distribution_type::in, list(call_site_static)::in,
> +    list(call_site_static)::out) is det.
> +
> +compute_css_list_above_threshold(Index, Deep, Threshold, Distribution,
> +        !CSSAcc) :-
> +    array.size(Deep ^ call_site_statics, Size),
> +    ( Index = Size ->
> +        true
> +    ;
> +        CallSiteCall = array.lookup(Deep ^ call_site_calls, Index),
> +        CSDListList = map.values(CallSiteCall),
> +        CSDList = list.condense(CSDListList),
> +        list.length(CSDList, NumCSD),
> +        ( NumCSD = 0 ->
> +            % The CSS doesn't have any CSDs.
> +            Callseqs = 0
> +        ;
> +            (
> +                Distribution = average,
> +                list.foldr(sum_callseqs_csd_ptr(Deep), CSDList,
> +                    0, SumCallseqs),
> +                % NOTE: we have checked that NumCSD is not zero above.
> +                Callseqs = SumCallseqs // NumCSD
> +            ;
> +                Distribution = median,
> +                list.sort(compare_csd_ptr(Deep), CSDList,
> CSDListSorted),
> +                IndexMedian = NumCSD // 2,
> +                list.index0_det(CSDListSorted, IndexMedian, MedianPtr),
> +                sum_callseqs_csd_ptr(Deep, MedianPtr, 0, Callseqs)
> +            )
> +        ),
> +        ( Callseqs >= Threshold ->
> +            CSS = array.lookup(Deep ^ call_site_statics, Index),
> +            !:CSSAcc = [ CSS | !.CSSAcc ],
> +            compute_css_list_above_threshold(Index + 1, Deep,
> Threshold,
> +                Distribution, !CSSAcc)
> +        ;
> +            compute_css_list_above_threshold(Index + 1, Deep,
> Threshold,
> +                Distribution, !CSSAcc)
> +        )
> +    ).
> +
> +    % Adds the callseqs (own and desc) of CSDPtr to the accumulator.
> +    %
> +:- pred sum_callseqs_csd_ptr(deep::in, call_site_dynamic_ptr::in,
> +    int::in, int::out) is det.
> +
> +sum_callseqs_csd_ptr(Deep, CSDPtr, !Sum) :-
> +    lookup_call_site_dynamics(Deep ^ call_site_dynamics, CSDPtr, CSD),
> +    lookup_csd_desc(Deep ^ csd_desc, CSDPtr, IPO),
> +    !:Sum = !.Sum + callseqs(CSD ^ csd_own_prof) +
> inherit_callseqs(IPO).
> +
> +    % Compares 2 CSDPtr on the basis of their callseqs (own and

s/2 CSDPTR/two CSD pointers/

> +    % desc).
> +    %
> +:- pred compare_csd_ptr(deep::in, call_site_dynamic_ptr::in,
> +    call_site_dynamic_ptr::in, comparison_result::out) is det.
> +
> +compare_csd_ptr(Deep, CSDPtrA, CSDPtrB, Result) :-
> +    sum_callseqs_csd_ptr(Deep, CSDPtrA, 0, SumA),
> +    sum_callseqs_csd_ptr(Deep, CSDPtrB, 0, SumB),
> +    compare(Result, SumA, SumB).
> +
> +    % Generates a profiling feedback file that contains the CSSs whose
> +    % CSD's average/median callseqs (own and desc) exceed the given
> threshold.
> +    %

...

> +:- pred generate_file(list(call_site_static)::in, deep::in,
> +    distribution_type::in, int::in, string::in, io::di, io::uo) is det.

I would rename this predicate to generate_feedback_file - the name
generate_file seems a bit too generic.

> +generate_file(CSSList, Deep, Distribution, Threshold, Output, !IO) :-
> +    io.open_output(Output, Result, !IO),
> +    (
> +        Result = io.error(Err),
> +        io.stderr_stream(Stderr, !IO),
> +        io.write_string(Stderr, io.error_message(Err) ++ "\n", !IO)
> +    ;
> +        Result = ok(OutStrm),

s/OutStrm/Stream/

> +        io.write_string(OutStrm, "Profiling feedback file\n", !IO),
> +        io.write_string(OutStrm, "Version = 1.0\n", !IO),
> +        (
> +            Distribution = average,
> +            io.write_string(OutStrm, "Distribution = average\n", !IO)
> +        ;
> +            Distribution = median,
> +            io.write_string(OutStrm, "Distribution = median\n", !IO)
> +        ),
> +        io.format(OutStrm, "Threshold = %i\n", [i(Threshold)], !IO),
> +        write_css_list(CSSList, Deep, OutStrm, !IO),
> +        io.close_output(OutStrm, !IO)
> +    ).

...

> +    % Writes to the output the list of CSSs
> +    %
> +:- pred write_css_list(list(call_site_static)::in, deep::in,
> output_stream::in,
> +    io::di, io::uo) is det.
> +
> +write_css_list([], _, _, !IO).
> +write_css_list([ CSS | CSSList0 ], Deep, OutStrm, !IO) :-
> +
> +    % Prints the caller
> +    lookup_proc_statics(Deep ^ proc_statics, CSS ^ css_container,
> Caller),
> +    io.write_string(OutStrm, Caller ^ ps_raw_id ++ " ", !IO),
> +
> +    % Prints the slot number of the call_site_static
> +    io.write_int(OutStrm, CSS ^ css_slot_num, !IO),
> +    io.write_string(OutStrm, " ", !IO),
> +
> +    % Prints the callee
> +    (
> +        CSS ^ css_kind = normal_call_and_callee(Ps_ptr, _),

s/Ps_ptr/PS_Ptr/

Julien.
--------------------------------------------------------------------------
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