[m-rev.] for review: new module mdprof_CSS_above_threshold
Ralph Becket
rafe at csse.unimelb.edu.au
Wed Oct 18 11:40:23 AEST 2006
[Forwarded by Ralph because Jerome is having e-mail trouble on this list.]
----- 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.
%-----------------------------------------------------------------------------%
% 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.
%-----------------------------------------------------------------------------%
%
% Author: tannier.
%
% This module contains the code for writing to a file the call site statics
% for which the matching call site dynamics have an average/median callseqs
% above a given threshold.
%
%-----------------------------------------------------------------------------%
:- module mdprof_CSS_above_threshold.
:- interface.
:- import_module io.
%-----------------------------------------------------------------------------%
:- pred main(io::di, io::uo) is det.
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
:- implementation.
:- import_module profile.
:- import_module list.
:- import_module array.
:- import_module measurements.
:- import_module string.
:- import_module require.
:- import_module int.
:- import_module library.
:- import_module startup.
:- import_module char.
:- import_module getopt.
:- import_module bool.
:- import_module conf.
:- import_module maybe.
:- import_module map.
%-----------------------------------------------------------------------------%
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),
(
Help = yes,
write_help_message(ProgName, !IO)
;
Help = no
),
(
Version = yes,
io.write_string(string.format("%s Version 1.0\n", [s(ProgName)]),
!IO)
;
Version = no
),
(
Help = no,
Version = no
->
( Args = [Input, Output] ->
lookup_string_option(Options, distrib, Distrib),
( construct_distrib(Distrib, Distrib_type) ->
lookup_int_option(Options, threshold, Threshold),
read_deep_file(Input, Maybe_error, !IO),
(
Maybe_error = ok(Deep),
compute_list_CSS_above_threshold(0, Deep, Threshold,
Distrib_type, [], List_CSS_above_threshold),
generate_file(List_CSS_above_threshold, Deep,
Distrib_type, Threshold, Output, !IO)
;
Maybe_error = error(Error),
io.set_exit_status(1, !IO),
io.format("%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)
)
;
true
)
;
MaybeOptions = error(Msg),
io.set_exit_status(1, !IO),
io.format("%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 should specify the following option:\n", []),
io.format("--threshold <value>\n", []),
io.format(" Set the threshold to <value>.\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("--distrib average|median\n",[]),
io.format(" average : writes to the output the call site\n",[]),
io.format(" statics for which the matching call site.\n",[]),
io.format(" dynamics have an average callseqs above.\n",[]),
io.format(" the specified threshold (default option).\n",[]),
io.format(" median : writes to the output the call site\n",[]),
io.format(" statics for which the matching call site.\n",[]),
io.format(" dynamics have a median callseqs above.\n",[]),
io.format(" the specified threshold.\n",[]).
%-----------------------------------------------------------------------------%
% Reads a deep data file.
%
:- pred read_deep_file(string::in, maybe_error(deep)::out, io::di, io::uo)
is det.
read_deep_file(Input, Maybe_error, !IO) :-
server_name(Machine, !IO),
io.stdout_stream(Stdout, !IO),
MaybeOutput = yes(Stdout),
read_and_startup(Machine, [Input], no, MaybeOutput, [], [], Maybe_error,
!IO).
% Determines the call site statics whose call site dynamics have an
% average/median above a given threshold.
%
:- pred compute_list_CSS_above_threshold(int::in, deep::in, int::in,
distrib_type::in, list(call_site_static)::in, list(call_site_static)::out)
is det.
compute_list_CSS_above_threshold(Index, Deep, Threshold, Distrib, Acc, List_CSS) :-
array.size(Deep ^ call_site_statics, Size),
( Index = Size ->
List_CSS = Acc
;
Call_site_call = array.lookup(Deep ^ call_site_calls, Index),
List_list_CSD = map.values(Call_site_call),
List_CSD = list.condense(List_list_CSD),
list.length(List_CSD, Length_List_CSD),
( Length_List_CSD = 0 ->
% the call_site_static doesn't have any call_site_dynamics
Callseqs = 0
;
(
Distrib = average,
foldr(sum_callseqs_CSD_ptr(Deep), List_CSD, 0, Sum_callseqs),
Callseqs = Sum_callseqs // Length_List_CSD
;
Distrib = median,
list.sort(compare_CSD_ptr(Deep), List_CSD,
List_CSD_sorted),
Index_median = Length_List_CSD // 2,
list.index0_det(List_CSD_sorted, Index_median, Median_ptr),
sum_callseqs_CSD_ptr(Deep, Median_ptr, 0, Callseqs)
)
),
( Callseqs >= Threshold ->
Call_site_static = array.lookup(Deep ^ call_site_statics, Index),
Acc0 = [Call_site_static | Acc],
compute_list_CSS_above_threshold(Index + 1, Deep, Threshold,
Distrib, Acc0, List_CSS)
;
compute_list_CSS_above_threshold(Index + 1, Deep, Threshold,
Distrib, Acc, List_CSS)
)
).
% Adds the callseqs (own and desc) of call_site_dynamic_ptr 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, CSD_ptr, Acc, Sum) :-
lookup_call_site_dynamics(Deep ^ call_site_dynamics, CSD_ptr, CSD),
lookup_csd_desc(Deep ^ csd_desc, CSD_ptr, IPO),
Sum = Acc + callseqs(CSD ^ csd_own_prof) + inherit_callseqs(IPO).
% Compares 2 call_site_dynamic_ptr 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, CSD_ptr1, CSD_ptr2, Result) :-
sum_callseqs_CSD_ptr(Deep, CSD_ptr1, 0, Sum1),
sum_callseqs_CSD_ptr(Deep, CSD_ptr2, 0, Sum2),
compare(Result, Sum1, Sum2).
% Generates the profiling feedback file which contains the call site statics
% whose call site dynamics have an average/median callseqs (own and desc)
% above the threshold.
%
:- pred generate_file(list(call_site_static)::in, deep::in,
distrib_type::in, int::in, string::in, io::di, io::uo) is det.
generate_file(List_CSS, Deep, Distrib, Threshold, Output, !IO) :-
io.open_output(Output, Result, !IO),
(
Result = io.error(Err),
io.write_string(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),
(
Distrib = average,
io.write_string(OutStrm, "Distrib = average\n", !IO)
;
Distrib = median,
io.write_string(OutStrm, "Distrib = median\n", !IO)
),
io.write_string(OutStrm, string.format("Threshold = %i\n",
[i(Threshold)]), !IO),
write_list_CSS(List_CSS, Deep, OutStrm, !IO),
io.close_output(OutStrm, !IO)
).
% Writes to the output the list of call site static
%
:- pred write_list_CSS(list(call_site_static)::in, deep::in, output_stream::in,
io::di, io::uo) is det.
write_list_CSS(List_CSS, Deep, OutStrm, !IO) :-
(
List_CSS=[]
;
List_CSS=[CSS | List_CSS0],
% 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.write_string(OutStrm, string.format("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_list_CSS(List_CSS0, Deep, OutStrm, !IO)
).
%-----------------------------------------------------------------------------%
:- type option
---> threshold
; help
; version
; distrib.
:- type distrib_type
---> average
; median.
:- type options ---> options.
:- type option_table == (option_table(option)).
:- pred short(char::in, option::out) is semidet.
short('t', threshold).
short('h', help).
short('v', version).
short('d', distrib).
:- pred long(string::in, option::out) is semidet.
long("threshold", threshold).
long("help", help).
long("version", version).
long("distrib", distrib).
:- pred defaults(option::out, option_data::out) is multi.
defaults(threshold, int(100000)).
defaults(help, bool(no)).
defaults(version, bool(no)).
defaults(distrib, string("average")).
:- pred construct_distrib(string::in, distrib_type::out) is semidet.
construct_distrib("average", average).
construct_distrib("median", median).
%-----------------------------------------------------------------------------%
:- end_module mdprof_CSS_above_threshold.
%-----------------------------------------------------------------------------%
----- End forwarded message -----
--------------------------------------------------------------------------
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