[m-rev.] for review: new module mdprof_CSS_above_threshold
Jerome Tannier
jerome.tannier at student.fundp.ac.be
Thu Oct 19 13:45:13 AEST 2006
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: Mmakefile
===================================================================
RCS file: /home/mercury1/repository/mercury/Mmakefile,v
retrieving revision 1.114
diff -u -r1.114 Mmakefile
--- Mmakefile 2 Oct 2006 06:30:34 -0000 1.114
+++ Mmakefile 18 Oct 2006 07:39:45 -0000
@@ -141,7 +141,8 @@
ifeq ("$(ENABLE_DEEP_PROFILER)","yes")
dep_deep_profiler: deep_profiler/$(deps_subdir)mdprof_cgi.dep \
deep_profiler/$(deps_subdir)mdprof_test.dep \
- deep_profiler/$(deps_subdir)mdprof_dump.dep
+ deep_profiler/$(deps_subdir)mdprof_dump.dep \
+ deep_profiler/$(deps_subdir)mdprof_feedback.dep
else
dep_deep_profiler:
endif
@@ -158,6 +159,10 @@
library/$(deps_subdir)$(STD_LIB_NAME).dep
+cd deep_profiler && $(SUBDIR_MMAKE) mdprof_dump.depend
+deep_profiler/$(deps_subdir)mdprof_feedback.dep: \
+ library/$(deps_subdir)$(STD_LIB_NAME).dep
+ +cd deep_profiler && $(SUBDIR_MMAKE) mdprof_feedback.depend
+
# depend_library MUST be done before depend_compiler and
depend_profiler
.PHONY: depend
Index: deep_profiler/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/mercury/deep_profiler/Mmakefile,v
retrieving revision 1.18
diff -u -r1.18 Mmakefile
--- deep_profiler/Mmakefile 9 Oct 2006 07:13:37 -0000 1.18
+++ deep_profiler/Mmakefile 18 Oct 2006 07:39:45 -0000
@@ -20,7 +20,7 @@
# can be found by `mmc --make'.
include Mercury.options
-ALL_DEEP_MODULES=mdprof_cgi mdprof_test mdprof_dump
+ALL_DEEP_MODULES=mdprof_cgi mdprof_test mdprof_dump mdprof_feedback
ifeq ("$(ENABLE_DEEP_PROFILER)","yes")
MAIN_TARGET=all
@@ -71,6 +71,8 @@
mdprof_test: $(LIBRARY_DIR)/lib$(STD_LIB_NAME).$A
mdprof_dump: $(RUNTIME_DIR)/lib$(RT_LIB_NAME).$A
mdprof_dump: $(LIBRARY_DIR)/lib$(STD_LIB_NAME).$A
+mdprof_feedback: $(RUNTIME_DIR)/lib$(RT_LIB_NAME).$A
+mdprof_feedback: $(LIBRARY_DIR)/lib$(STD_LIB_NAME).$A
# XXX Should also depend on $(BOEHM_GC_DIR)/libgc(_prof).$A, but only
# if in .gc(.prof) grade.
endif
@@ -78,6 +80,7 @@
$(cs_subdir)mdprof_cgi_init.c: $(UTIL_DIR)/mkinit
$(cs_subdir)mdprof_test_init.c: $(UTIL_DIR)/mkinit
$(cs_subdir)mdprof_dump_init.c: $(UTIL_DIR)/mkinit
+$(cs_subdir)mdprof_feedback_init.c: $(UTIL_DIR)/mkinit
#-----------------------------------------------------------------------------#
@@ -97,7 +100,7 @@
.PHONY: tags
tags: .deep.tags
-DEEP_MS = $(mdprof_cgi.ms) $(mdprof_test.ms) $(mdprof_dump.ms)
+DEEP_MS = $(mdprof_cgi.ms) $(mdprof_test.ms) $(mdprof_dump.ms)
$(mdprof_feedback.ms)
.deep.tags: $(MTAGS) $(DEEP_MS) $(LIBRARY_DIR)/*.m
$(MTAGS) $(DEEP_MS) $(LIBRARY_DIR)/*.m
@@ -113,7 +116,8 @@
.PHONY: dates
dates:
- touch $(mdprof_cgi.dates) $(mdprof_test.dates) $(mdprof_dump.dates)
+ touch $(mdprof_cgi.dates) $(mdprof_test.dates) $(mdprof_dump.dates) \
+ $(mdprof_feedback.dates)
#-----------------------------------------------------------------------------#
@@ -121,9 +125,11 @@
os: $(mdprof_cgi.os) $(os_subdir)mdprof_cgi_init.o
os: $(mdprof_test.os) $(os_subdir)mdprof_test_init.o
os: $(mdprof_dump.os) $(os_subdir)mdprof_dump_init.o
+os: $(mdprof_feedback.os) $(os_subdir)mdprof_feedback_init.o
cs: $(mdprof_cgi.cs) $(cs_subdir)mdprof_cgi_init.c
cs: $(mdprof_test.cs) $(cs_subdir)mdprof_test_init.c
cs: $(mdprof_dump.cs) $(cs_subdir)mdprof_dump_init.c
+cs: $(mdprof_feedback.cs) $(cs_subdir)mdprof_feedback_init.c
#-----------------------------------------------------------------------------#
@@ -144,7 +150,7 @@
# by different paths.
.PHONY: install_cgi_progs
-install_cgi_progs: mdprof_cgi
+install_cgi_progs: mdprof_cgi mdprof_dump mdprof_test mdprof_feedback
# $(INSTALL_CGI_DIR) is likely to be writeable only by root or
# the www system administrator, which is why we don't consider a
# failure of this action to be an error. If the command fails,
@@ -174,6 +180,8 @@
$(INSTALL_MERC_BIN_DIR)/mdprof_test
cp `vpath_find mdprof_dump$(EXT_FOR_EXE)` \
$(INSTALL_MERC_BIN_DIR)/mdprof_dump
+ cp `vpath_find mdprof_feedback$(EXT_FOR_EXE)` \
+ $(INSTALL_MERC_BIN_DIR)/mdprof_feedback
uninstall:
# We try to uninstall mdprof_cgi, but failure to do so is not an
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.
+% 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.
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module conf.
+:- import_module measurements.
+:- import_module profile.
+:- import_module startup.
+
+:- import_module array.
+:- import_module bool.
+:- import_module char.
+:- import_module getopt.
+:- import_module int.
+:- import_module library.
+:- import_module list.
+:- import_module map.
+:- import_module maybe.
+:- import_module require.
+:- import_module string.
+
+%-----------------------------------------------------------------------------%
+
+main(!IO) :-
+ io.progname_base("Profiling feedback program", ProgName, !IO),
+ 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)
+ ; 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
\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.
+ %
+:- 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
+ % 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.
+
+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),
+ 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, _),
+ lookup_proc_statics(Deep ^ proc_statics, Ps_ptr, Callee),
+ io.format(OutStrm, "normal_call %s\n", [s(Callee ^
ps_raw_id)], !IO)
+ ;
+ CSS ^ css_kind = special_call_and_no_callee,
+ io.write_string(OutStrm, "special_call\n", !IO)
+ ;
+ CSS ^ css_kind = higher_order_call_and_no_callee,
+ io.write_string(OutStrm, "higher_order_call\n", !IO)
+ ;
+ CSS ^ css_kind = method_call_and_no_callee,
+ io.write_string(OutStrm, "method_call\n", !IO)
+ ;
+ CSS ^ css_kind = callback_and_no_callee,
+ io.write_string(OutStrm, "callback\n", !IO)
+ ),
+ write_css_list(CSSList0, Deep, OutStrm, !IO).
+
+%-----------------------------------------------------------------------------%
+
+:- type option
+ ---> threshold
+ ; help
+ ; verbose
+ ; version
+ ; distribution.
+
+:- type distribution_type
+ ---> average
+ ; median.
+
+:- type option_table == option_table(option).
+
+:- pred short(char::in, option::out) is semidet.
+
+short('V', verbose).
+short('t', threshold).
+short('h', help).
+short('v', version).
+short('d', distribution).
+
+
+:- pred long(string::in, option::out) is semidet.
+
+long("threshold", threshold).
+long("help", help).
+long("verbose", verbose).
+long("version", version).
+long("distrib", distribution).
+long("distribution", distribution).
+
+:- pred defaults(option::out, option_data::out) is multi.
+
+defaults(threshold, int(100000)).
+defaults(help, bool(no)).
+defaults(verbose, bool(no)).
+defaults(version, bool(no)).
+defaults(distribution, string("average")).
+
+:- pred construct_distribution(string::in, distribution_type::out) is
semidet.
+
+construct_distribution("average", average).
+construct_distribution("median", median).
+
+%-----------------------------------------------------------------------------%
+:- end_module mdprof_feedback.
+%-----------------------------------------------------------------------------%
On Thu, 2006-10-19 at 11:48 +1000, Jerome Tannier wrote:
> For review.
>
> The file has been renamed to mdprof_feedback.m.
>
> Jerome.
>
> On Wed, 2006-10-18 at 18:09 +1000, Julien Fischer wrote:
> > On Wed, 18 Oct 2006, Ralph Becket wrote:
> >
> > > [Forwarded by Ralph because Jerome is having e-mail trouble on this list.]
> > >
> >
> > I think this should be fixed now.
> >
> > > ----- Forwarded message from Jerome Tannier <jerome.tannier at student.fundp.ac.be> -----
> > >
> > > Branches: main
> > >
> > > deep_profiler/mdprof_CSS_above_threshold.m:
> > > New module which writes to a file the list of call site statics
> > > whose matching call site dynamics have an average/median
> > > callseqs above a given threshold.
> > >
> >
> > Jerome and I have discussed this diff in person and also modified various
> > Mmakefiles and so forth. There should be a new diff posted tommorrow
> > some time.
> >
> > 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
> > --------------------------------------------------------------------------
--------------------------------------------------------------------------
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