[m-rev.] for review: add value-threshold of top procedures to deep profiler.

Paul Bone pbone at csse.unimelb.edu.au
Mon Sep 24 23:57:53 AEST 2007


For review by anyone.

Estimated hours taken: 1.5

Branches: main

Changes to the deep profiler: Added ability to select top procedures based on
a raw threshold rather than a percentage.  I've added new links in the main
screen of the mdprof_cgi program demonstrating this feature.

deep_profiler/interface.m
    Added extra value for display_limit type, threshold_value to represent this
    new value-based threshold of procedures.
    Also altered string conversion functions for limits to include this new
    value and ensure it's disambiguated against existing values.

deep_profiler/query.m:
    Added links to main screen to access reports using this feature.  Default
    thresholds have been chosen, if anyone has better values to choose for
    these than the ones I have please let me know.

deep_profiler/top_procs.m:
    Altered find_top_procs to accept this limit and properly remove procedures
    from it's output not matching it.
    Created new clauses to find sort predicates for the new value.
    Created new clauses to find threshold predicates for the new value.
    Created new threshold predicates to select rows that are above the
    threshold.

Index: deep_profiler/interface.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/interface.m,v
retrieving revision 1.17
diff -u -r1.17 interface.m
--- deep_profiler/interface.m	2 Apr 2007 02:42:32 -0000	1.17
+++ deep_profiler/interface.m	24 Sep 2007 12:34:27 -0000
@@ -167,9 +167,13 @@
             % rank_range(M, N): display procedures with rank M to N,
             % both inclusive.
 
-    ;       threshold(float).
+    ;       threshold(float)
             % threshold(Percent): display procedures whose cost is at least
             % Percent% of the whole program's cost.
+    
+    ;       threshold_value(float).
+            % threshold_value(Value): display procedures whose cost is at least
+            % this value.
 
 :- type preferences_indication
     --->    given_pref(preferences)
@@ -970,7 +974,9 @@
 limit_to_string(rank_range(Lo, Hi)) =
     string.format("%d%c%d", [i(Lo), c(limit_separator_char), i(Hi)]).
 limit_to_string(threshold(Threshold)) =
-    string.format("%g", [f(Threshold)]).
+    string.format("p%g", [f(Threshold)]).
+limit_to_string(threshold_value(Value)) =
+    string.format("v%g", [f(Value)]).
 
 :- pred string_to_limit(string::in, display_limit::out) is semidet.
 
@@ -983,10 +989,16 @@
     ->
         Limit = rank_range(First, Last)
     ;
-        string.to_float(LimitStr, Threshold)
+        string.append("p", PercentStr, LimitStr),
+        string.to_float(PercentStr, Threshold)
     ->
         Limit = threshold(Threshold)
     ;
+        string.append("v", ValueStr, LimitStr),
+        string.to_float(ValueStr, Value)
+    ->
+        Limit = threshold_value(Value)
+    ;
         fail
     ).
 
Index: deep_profiler/query.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/query.m,v
retrieving revision 1.16
diff -u -r1.16 query.m
--- deep_profiler/query.m	2 Apr 2007 06:10:43 -0000	1.16
+++ deep_profiler/query.m	24 Sep 2007 12:34:30 -0000
@@ -49,6 +49,7 @@
 :- import_module string.
 :- import_module univ.
 :- import_module unit.
+:- import_module float.
 
 %-----------------------------------------------------------------------------%
 
@@ -390,7 +391,13 @@
             menu_item(Deep, Pref,
                 deep_cmd_top_procs(threshold(1.0), cost_time, self_and_desc,
                     overall),
-                "Procedures above 1% threshold: time, self+descendants.")
+                "Procedures above 1% threshold: time, self+descendants.") ++
+            "<li>\n" ++
+            menu_item(Deep, Pref,
+                deep_cmd_top_procs(threshold_value(100.0), cost_time, 
+                    self_and_desc, overall),
+                "Procedures above 1 second threshold: " ++ 
+                    "time, self+descendants.")
         ;
             ""
         ) ++
@@ -406,6 +413,13 @@
             ++
         "<li>\n" ++
         menu_item(Deep, Pref,
+            deep_cmd_top_procs(threshold_value(1000000.0), cost_callseqs, 
+                self_and_desc, overall),
+            "Procedures above 1,000,000 callseqs threshold: callseqs, " ++
+                "self+descendants.")
+            ++
+        "<li>\n" ++
+        menu_item(Deep, Pref,
             deep_cmd_top_procs(threshold(0.1), cost_words, self, overall),
             "Procedures above 0.1% threshold: words, self.") ++
         "<li>\n" ++
@@ -414,6 +428,13 @@
                 overall),
             "Procedures above 1% threshold: words, self+descendants.")
             ++
+        "<li>\n" ++
+        % This is 2M words or 8MB on ia32
+        menu_item(Deep, Pref,
+            deep_cmd_top_procs(threshold_value(float(1024 * 1024 * 2)), 
+                cost_words, self_and_desc, overall),
+            "Procedures above 2M words threshold: words, self+descendants.")
+            ++
         "</ul>\n" ++
         "<p>\n" ++
         present_stats(Deep) ++
Index: deep_profiler/top_procs.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/top_procs.m,v
retrieving revision 1.10
diff -u -r1.10 top_procs.m
--- deep_profiler/top_procs.m	1 Dec 2006 15:03:47 -0000	1.10
+++ deep_profiler/top_procs.m	24 Sep 2007 12:34:31 -0000
@@ -94,7 +94,22 @@
             )
         ;
             Limit = threshold(Threshold),
-            find_threshold_predicate(Sort, InclDesc,
+            find_threshold_percent_predicate(Sort, InclDesc,
+                ThresholdCompatible, RawThresholdPred),
+            (
+                ThresholdCompatible = no,
+                MaybeTopPSIs = error("bad threshold specification")
+            ;
+                ThresholdCompatible = yes,
+                ThresholdPred = (pred(PSI::in) is semidet :-
+                    RawThresholdPred(Deep, Threshold, PSI)
+                ),
+                list.takewhile(ThresholdPred, DescendingPSIs, TopPSIs, _),
+                MaybeTopPSIs = ok(TopPSIs)
+            )
+        ;
+            Limit = threshold_value(Threshold),
+            find_threshold_value_predicate(Sort, InclDesc,
                 ThresholdCompatible, RawThresholdPred),
             (
                 ThresholdCompatible = no,
@@ -198,39 +213,73 @@
 find_top_sort_predicate(cost_words,  self_and_desc, per_call, yes,
     compare_ps_words_both_percall,  filter_ps_words_both).
 
-:- pred find_threshold_predicate(cost_kind::in, include_descendants::in,
+:- pred find_threshold_percent_predicate(cost_kind::in, include_descendants::in,
     bool::out, pred(deep, float, int)::out(pred(in, in, in) is semidet))
     is det.
 
-find_threshold_predicate(cost_calls,  self,          no,
-    threshold_ps_time_self).
-find_threshold_predicate(cost_calls,  self_and_desc, no,
-    threshold_ps_time_self).
-
-find_threshold_predicate(cost_redos,  self,          no,
-    threshold_ps_time_self).
-find_threshold_predicate(cost_redos,  self_and_desc, no,
-    threshold_ps_time_self).
-
-find_threshold_predicate(cost_time,   self,          yes,
-    threshold_ps_time_self).
-find_threshold_predicate(cost_time,   self_and_desc, yes,
-    threshold_ps_time_both).
-
-find_threshold_predicate(cost_callseqs, self,          yes,
-    threshold_ps_callseqs_self).
-find_threshold_predicate(cost_callseqs, self_and_desc, yes,
-    threshold_ps_callseqs_both).
-
-find_threshold_predicate(cost_allocs, self,          yes,
-    threshold_ps_allocs_self).
-find_threshold_predicate(cost_allocs, self_and_desc, yes,
-    threshold_ps_allocs_both).
-
-find_threshold_predicate(cost_words,  self,          yes,
-    threshold_ps_words_self).
-find_threshold_predicate(cost_words,  self_and_desc, yes,
-    threshold_ps_words_both).
+find_threshold_percent_predicate(cost_calls,  self,          no,
+    threshold_percent_ps_time_self).
+find_threshold_percent_predicate(cost_calls,  self_and_desc, no,
+    threshold_percent_ps_time_self).
+
+find_threshold_percent_predicate(cost_redos,  self,          no,
+    threshold_percent_ps_time_self).
+find_threshold_percent_predicate(cost_redos,  self_and_desc, no,
+    threshold_percent_ps_time_self).
+
+find_threshold_percent_predicate(cost_time,   self,          yes,
+    threshold_percent_ps_time_self).
+find_threshold_percent_predicate(cost_time,   self_and_desc, yes,
+    threshold_percent_ps_time_both).
+
+find_threshold_percent_predicate(cost_callseqs, self,          yes,
+    threshold_percent_ps_callseqs_self).
+find_threshold_percent_predicate(cost_callseqs, self_and_desc, yes,
+    threshold_percent_ps_callseqs_both).
+
+find_threshold_percent_predicate(cost_allocs, self,          yes,
+    threshold_percent_ps_allocs_self).
+find_threshold_percent_predicate(cost_allocs, self_and_desc, yes,
+    threshold_percent_ps_allocs_both).
+
+find_threshold_percent_predicate(cost_words,  self,          yes,
+    threshold_percent_ps_words_self).
+find_threshold_percent_predicate(cost_words,  self_and_desc, yes,
+    threshold_percent_ps_words_both).
+
+:- pred find_threshold_value_predicate(cost_kind::in, include_descendants::in,
+    bool::out, pred(deep, float, int)::out(pred(in, in, in) is semidet))
+    is det.
+
+find_threshold_value_predicate(cost_calls,  self,          no,
+    threshold_value_ps_time_self).
+find_threshold_value_predicate(cost_calls,  self_and_desc, no,
+    threshold_value_ps_time_self).
+
+find_threshold_value_predicate(cost_redos,  self,          no,
+    threshold_value_ps_time_self).
+find_threshold_value_predicate(cost_redos,  self_and_desc, no,
+    threshold_value_ps_time_self).
+
+find_threshold_value_predicate(cost_time,   self,          yes,
+    threshold_value_ps_time_self).
+find_threshold_value_predicate(cost_time,   self_and_desc, yes,
+    threshold_value_ps_time_both).
+
+find_threshold_value_predicate(cost_callseqs, self,          yes,
+    threshold_value_ps_callseqs_self).
+find_threshold_value_predicate(cost_callseqs, self_and_desc, yes,
+    threshold_value_ps_callseqs_both).
+
+find_threshold_value_predicate(cost_allocs, self,          yes,
+    threshold_value_ps_allocs_self).
+find_threshold_value_predicate(cost_allocs, self_and_desc, yes,
+    threshold_value_ps_allocs_both).
+
+find_threshold_value_predicate(cost_words,  self,          yes,
+    threshold_value_ps_words_self).
+find_threshold_value_predicate(cost_words,  self_and_desc, yes,
+    threshold_value_ps_words_both).
 
 %-----------------------------------------------------------------------------%
 
@@ -602,9 +651,93 @@
 
 %-----------------------------------------------------------------------------%
 
-:- pred threshold_ps_time_self(deep::in, float::in, int::in) is semidet.
+:- pred threshold_value_ps_time_self(deep::in, float::in, int::in) is semidet.
+
+threshold_value_ps_time_self(Deep, Threshold, PSI) :-
+    PSOwn = Deep ^ ps_own,
+    array.lookup(PSOwn, PSI, Own),
+    OwnQuanta = quanta(Own),
+    float(OwnQuanta) > Threshold.
+
+:- pred threshold_value_ps_time_both(deep::in, float::in, int::in) is semidet.
+
+threshold_value_ps_time_both(Deep, Threshold, PSI) :-
+    PSOwn = Deep ^ ps_own,
+    PSDesc = Deep ^ ps_desc,
+    array.lookup(PSOwn, PSI, Own),
+    array.lookup(PSDesc, PSI, Desc),
+    OwnQuanta = quanta(Own),
+    DescQuanta = inherit_quanta(Desc),
+    TotalQuanta = OwnQuanta + DescQuanta,
+    float(TotalQuanta) > Threshold.
+
+:- pred threshold_value_ps_callseqs_self(deep::in, float::in, int::in) 
+    is semidet.
+
+threshold_value_ps_callseqs_self(Deep, Threshold, PSI) :-
+    PSOwn = Deep ^ ps_own,
+    array.lookup(PSOwn, PSI, Own),
+    OwnCallSeqs = callseqs(Own),
+    float(OwnCallSeqs) > Threshold.
+
+:- pred threshold_value_ps_callseqs_both(deep::in, float::in, int::in) 
+    is semidet.
+
+threshold_value_ps_callseqs_both(Deep, Threshold, PSI) :-
+    PSOwn = Deep ^ ps_own,
+    PSDesc = Deep ^ ps_desc,
+    array.lookup(PSOwn, PSI, Own),
+    array.lookup(PSDesc, PSI, Desc),
+    OwnCallSeqs = callseqs(Own),
+    DescCallSeqs = inherit_callseqs(Desc),
+    TotalCallSeqs = OwnCallSeqs + DescCallSeqs,
+    float(TotalCallSeqs) > Threshold.
+
+:- pred threshold_value_ps_allocs_self(deep::in, float::in, int::in) is semidet.
+
+threshold_value_ps_allocs_self(Deep, Threshold, PSI) :-
+    PSOwn = Deep ^ ps_own,
+    array.lookup(PSOwn, PSI, Own),
+    OwnAlloc = allocs(Own),
+    float(OwnAlloc) > Threshold.
+
+:- pred threshold_value_ps_allocs_both(deep::in, float::in, int::in) is semidet.
+
+threshold_value_ps_allocs_both(Deep, Threshold, PSI) :-
+    PSOwn = Deep ^ ps_own,
+    PSDesc = Deep ^ ps_desc,
+    array.lookup(PSOwn, PSI, Own),
+    array.lookup(PSDesc, PSI, Desc),
+    OwnAlloc = allocs(Own),
+    DescAlloc = inherit_allocs(Desc),
+    TotalAlloc = OwnAlloc + DescAlloc,
+    float(TotalAlloc) > Threshold.
+
+:- pred threshold_value_ps_words_self(deep::in, float::in, int::in) is semidet.
+
+threshold_value_ps_words_self(Deep, Threshold, PSI) :-
+    PSOwn = Deep ^ ps_own,
+    array.lookup(PSOwn, PSI, Own),
+    OwnWords = words(Own),
+    float(OwnWords) > Threshold.
+
+:- pred threshold_value_ps_words_both(deep::in, float::in, int::in) is semidet.
+
+threshold_value_ps_words_both(Deep, Threshold, PSI) :-
+    PSOwn = Deep ^ ps_own,
+    PSDesc = Deep ^ ps_desc,
+    array.lookup(PSOwn, PSI, Own),
+    array.lookup(PSDesc, PSI, Desc),
+    OwnWords = words(Own),
+    DescWords = inherit_words(Desc),
+    TotalWords = OwnWords + DescWords,
+    float(TotalWords) > Threshold.
+
+%-----------------------------------------------------------------------------%
+
+:- pred threshold_percent_ps_time_self(deep::in, float::in, int::in) is semidet.
 
-threshold_ps_time_self(Deep, Threshold, PSI) :-
+threshold_percent_ps_time_self(Deep, Threshold, PSI) :-
     PSOwn = Deep ^ ps_own,
     array.lookup(PSOwn, PSI, Own),
     RootOwn = root_own_info(Deep),
@@ -615,9 +748,9 @@
     RootTotalQuanta = RootOwnQuanta + RootDescQuanta,
     100.0 * float(OwnQuanta) > Threshold * float(RootTotalQuanta).
 
-:- pred threshold_ps_time_both(deep::in, float::in, int::in) is semidet.
+:- pred threshold_percent_ps_time_both(deep::in, float::in, int::in) is semidet.
 
-threshold_ps_time_both(Deep, Threshold, PSI) :-
+threshold_percent_ps_time_both(Deep, Threshold, PSI) :-
     PSOwn = Deep ^ ps_own,
     PSDesc = Deep ^ ps_desc,
     array.lookup(PSOwn, PSI, Own),
@@ -632,9 +765,9 @@
     RootTotalQuanta = RootOwnQuanta + RootDescQuanta,
     100.0 * float(TotalQuanta) > Threshold * float(RootTotalQuanta).
 
-:- pred threshold_ps_callseqs_self(deep::in, float::in, int::in) is semidet.
+:- pred threshold_percent_ps_callseqs_self(deep::in, float::in, int::in) is semidet.
 
-threshold_ps_callseqs_self(Deep, Threshold, PSI) :-
+threshold_percent_ps_callseqs_self(Deep, Threshold, PSI) :-
     PSOwn = Deep ^ ps_own,
     array.lookup(PSOwn, PSI, Own),
     RootOwn = root_own_info(Deep),
@@ -645,9 +778,9 @@
     RootTotalCallSeqs = RootOwnCallSeqs + RootDescCallSeqs,
     100.0 * float(OwnCallSeqs) > Threshold * float(RootTotalCallSeqs).
 
-:- pred threshold_ps_callseqs_both(deep::in, float::in, int::in) is semidet.
+:- pred threshold_percent_ps_callseqs_both(deep::in, float::in, int::in) is semidet.
 
-threshold_ps_callseqs_both(Deep, Threshold, PSI) :-
+threshold_percent_ps_callseqs_both(Deep, Threshold, PSI) :-
     PSOwn = Deep ^ ps_own,
     PSDesc = Deep ^ ps_desc,
     array.lookup(PSOwn, PSI, Own),
@@ -662,9 +795,9 @@
     RootTotalCallSeqs = RootOwnCallSeqs + RootDescCallSeqs,
     100.0 * float(TotalCallSeqs) > Threshold * float(RootTotalCallSeqs).
 
-:- pred threshold_ps_allocs_self(deep::in, float::in, int::in) is semidet.
+:- pred threshold_percent_ps_allocs_self(deep::in, float::in, int::in) is semidet.
 
-threshold_ps_allocs_self(Deep, Threshold, PSI) :-
+threshold_percent_ps_allocs_self(Deep, Threshold, PSI) :-
     PSOwn = Deep ^ ps_own,
     array.lookup(PSOwn, PSI, Own),
     RootOwn = root_own_info(Deep),
@@ -675,9 +808,9 @@
     RootTotalAlloc = RootOwnAlloc + RootDescAlloc,
     100.0 * float(OwnAlloc) > Threshold * float(RootTotalAlloc).
 
-:- pred threshold_ps_allocs_both(deep::in, float::in, int::in) is semidet.
+:- pred threshold_percent_ps_allocs_both(deep::in, float::in, int::in) is semidet.
 
-threshold_ps_allocs_both(Deep, Threshold, PSI) :-
+threshold_percent_ps_allocs_both(Deep, Threshold, PSI) :-
     PSOwn = Deep ^ ps_own,
     PSDesc = Deep ^ ps_desc,
     array.lookup(PSOwn, PSI, Own),
@@ -692,9 +825,9 @@
     RootTotalAlloc = RootOwnAlloc + RootDescAlloc,
     100.0 * float(TotalAlloc) > Threshold * float(RootTotalAlloc).
 
-:- pred threshold_ps_words_self(deep::in, float::in, int::in) is semidet.
+:- pred threshold_percent_ps_words_self(deep::in, float::in, int::in) is semidet.
 
-threshold_ps_words_self(Deep, Threshold, PSI) :-
+threshold_percent_ps_words_self(Deep, Threshold, PSI) :-
     PSOwn = Deep ^ ps_own,
     array.lookup(PSOwn, PSI, Own),
     RootOwn = root_own_info(Deep),
@@ -705,9 +838,9 @@
     RootTotalWords = RootOwnWords + RootDescWords,
     100.0 * float(OwnWords) > Threshold * float(RootTotalWords).
 
-:- pred threshold_ps_words_both(deep::in, float::in, int::in) is semidet.
+:- pred threshold_percent_ps_words_both(deep::in, float::in, int::in) is semidet.
 
-threshold_ps_words_both(Deep, Threshold, PSI) :-
+threshold_percent_ps_words_both(Deep, Threshold, PSI) :-
     PSOwn = Deep ^ ps_own,
     PSDesc = Deep ^ ps_desc,
     array.lookup(PSOwn, PSI, Own),
--------------------------------------------------------------------------
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