perf diff: Add 'delta-abs' compute method
authorNamhyung Kim <namhyung@kernel.org>
Fri, 10 Feb 2017 07:36:11 +0000 (16:36 +0900)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Mon, 13 Feb 2017 17:29:36 +0000 (14:29 -0300)
The 'delta-abs' compute method is same as 'delta' but shows entries with
bigger absolute delta first instead of sorting numerically.  This is
only useful together with -o option.

Below is default output (-c delta):

  $ perf diff -o 1 -c delta | grep -v ^# | head
    42.22%   +4.97%  [kernel.kallsyms]  [k] cfb_imageblit
     0.62%   +1.23%  [kernel.kallsyms]  [k] mutex_lock
             +1.15%  [kernel.kallsyms]  [k] copy_user_generic_string
     2.40%   +0.95%  [kernel.kallsyms]  [k] bit_putcs
     0.31%   +0.79%  [kernel.kallsyms]  [k] link_path_walk
             +0.64%  [kernel.kallsyms]  [k] kmem_cache_alloc
     0.00%   +0.57%  [kernel.kallsyms]  [k] __rcu_read_unlock
             +0.45%  [kernel.kallsyms]  [k] alloc_set_pte
     0.16%   +0.45%  [kernel.kallsyms]  [k] menu_select
             +0.41%  ld-2.24.so         [.] do_lookup_x

Now with 'delta-abs' it shows entries have bigger delta value either
positive or negative.

  $ perf diff -o 1 -c delta-abs | grep -v ^# | head
    42.22%   +4.97%  [kernel.kallsyms]  [k] cfb_imageblit
    12.72%   -3.01%  [kernel.kallsyms]  [k] intel_idle
     9.72%   -1.31%  [unknown]          [.] 0x0000000000411343
     0.62%   +1.23%  [kernel.kallsyms]  [k] mutex_lock
     2.40%   +0.95%  [kernel.kallsyms]  [k] bit_putcs
     0.31%   +0.79%  [kernel.kallsyms]  [k] link_path_walk
     1.35%   -0.71%  [kernel.kallsyms]  [k] smp_call_function_single
     0.00%   +0.57%  [kernel.kallsyms]  [k] __rcu_read_unlock
     0.16%   +0.45%  [kernel.kallsyms]  [k] menu_select
     0.72%   -0.44%  [kernel.kallsyms]  [k] lookup_fast

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/20170210073614.24584-2-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/Documentation/perf-diff.txt
tools/perf/builtin-diff.c

index 3e9490b9c5334486d9787d52e531e1002c917c47..af80284cd2f60ddaddbe48b5b45e51096c9d2e16 100644 (file)
@@ -86,7 +86,7 @@ OPTIONS
 
 -c::
 --compute::
-        Differential computation selection - delta,ratio,wdiff (default is delta).
+        Differential computation selection - delta,ratio,wdiff,delta-abs (default is delta).
         See COMPARISON METHODS section for more info.
 
 -p::
@@ -181,6 +181,10 @@ with:
     relative to how entries are filtered.  Use --percentage=absolute to
     prevent such fluctuation.
 
+delta-abs
+~~~~~~~~~
+Same as 'delta` method, but sort the result with the absolute values.
+
 ratio
 ~~~~~
 If specified the 'Ratio' column is displayed with value 'r' computed as:
index 933aeec46f4a128754ef586c07df8e6d7d81eae0..781c9e60bd213b35c792f4eafc4c0a67c47e66b6 100644 (file)
@@ -30,6 +30,7 @@ enum {
        PERF_HPP_DIFF__RATIO,
        PERF_HPP_DIFF__WEIGHTED_DIFF,
        PERF_HPP_DIFF__FORMULA,
+       PERF_HPP_DIFF__DELTA_ABS,
 
        PERF_HPP_DIFF__MAX_INDEX
 };
@@ -73,11 +74,13 @@ enum {
        COMPUTE_DELTA,
        COMPUTE_RATIO,
        COMPUTE_WEIGHTED_DIFF,
+       COMPUTE_DELTA_ABS,
        COMPUTE_MAX,
 };
 
 const char *compute_names[COMPUTE_MAX] = {
        [COMPUTE_DELTA] = "delta",
+       [COMPUTE_DELTA_ABS] = "delta-abs",
        [COMPUTE_RATIO] = "ratio",
        [COMPUTE_WEIGHTED_DIFF] = "wdiff",
 };
@@ -86,6 +89,7 @@ static int compute;
 
 static int compute_2_hpp[COMPUTE_MAX] = {
        [COMPUTE_DELTA]         = PERF_HPP_DIFF__DELTA,
+       [COMPUTE_DELTA_ABS]     = PERF_HPP_DIFF__DELTA_ABS,
        [COMPUTE_RATIO]         = PERF_HPP_DIFF__RATIO,
        [COMPUTE_WEIGHTED_DIFF] = PERF_HPP_DIFF__WEIGHTED_DIFF,
 };
@@ -111,6 +115,10 @@ static struct header_column {
                .name  = "Delta",
                .width = 7,
        },
+       [PERF_HPP_DIFF__DELTA_ABS] = {
+               .name  = "Delta Abs",
+               .width = 7,
+       },
        [PERF_HPP_DIFF__RATIO] = {
                .name  = "Ratio",
                .width = 14,
@@ -298,6 +306,7 @@ static int formula_fprintf(struct hist_entry *he, struct hist_entry *pair,
 {
        switch (compute) {
        case COMPUTE_DELTA:
+       case COMPUTE_DELTA_ABS:
                return formula_delta(he, pair, buf, size);
        case COMPUTE_RATIO:
                return formula_ratio(he, pair, buf, size);
@@ -461,6 +470,7 @@ static void hists__precompute(struct hists *hists)
 
                        switch (compute) {
                        case COMPUTE_DELTA:
+                       case COMPUTE_DELTA_ABS:
                                compute_delta(he, pair);
                                break;
                        case COMPUTE_RATIO:
@@ -498,6 +508,13 @@ __hist_entry__cmp_compute(struct hist_entry *left, struct hist_entry *right,
 
                return cmp_doubles(l, r);
        }
+       case COMPUTE_DELTA_ABS:
+       {
+               double l = fabs(left->diff.period_ratio_delta);
+               double r = fabs(right->diff.period_ratio_delta);
+
+               return cmp_doubles(l, r);
+       }
        case COMPUTE_RATIO:
        {
                double l = left->diff.period_ratio;
@@ -564,7 +581,7 @@ hist_entry__cmp_compute_idx(struct hist_entry *left, struct hist_entry *right,
        if (!p_left || !p_right)
                return p_left ? -1 : 1;
 
-       if (c != COMPUTE_DELTA) {
+       if (c != COMPUTE_DELTA && c != COMPUTE_DELTA_ABS) {
                /*
                 * The delta can be computed without the baseline, but
                 * others are not.  Put those entries which have no
@@ -606,6 +623,15 @@ hist_entry__cmp_delta(struct perf_hpp_fmt *fmt,
        return hist_entry__cmp_compute(right, left, COMPUTE_DELTA, d->idx);
 }
 
+static int64_t
+hist_entry__cmp_delta_abs(struct perf_hpp_fmt *fmt,
+                     struct hist_entry *left, struct hist_entry *right)
+{
+       struct data__file *d = fmt_to_data_file(fmt);
+
+       return hist_entry__cmp_compute(right, left, COMPUTE_DELTA_ABS, d->idx);
+}
+
 static int64_t
 hist_entry__cmp_ratio(struct perf_hpp_fmt *fmt,
                      struct hist_entry *left, struct hist_entry *right)
@@ -632,6 +658,14 @@ hist_entry__cmp_delta_idx(struct perf_hpp_fmt *fmt __maybe_unused,
                                           sort_compute);
 }
 
+static int64_t
+hist_entry__cmp_delta_abs_idx(struct perf_hpp_fmt *fmt __maybe_unused,
+                             struct hist_entry *left, struct hist_entry *right)
+{
+       return hist_entry__cmp_compute_idx(right, left, COMPUTE_DELTA_ABS,
+                                          sort_compute);
+}
+
 static int64_t
 hist_entry__cmp_ratio_idx(struct perf_hpp_fmt *fmt __maybe_unused,
                          struct hist_entry *left, struct hist_entry *right)
@@ -775,7 +809,7 @@ static const struct option options[] = {
        OPT_BOOLEAN('b', "baseline-only", &show_baseline_only,
                    "Show only items with match in baseline"),
        OPT_CALLBACK('c', "compute", &compute,
-                    "delta,ratio,wdiff:w1,w2 (default delta)",
+                    "delta,delta-abs,ratio,wdiff:w1,w2 (default delta)",
                     "Entries differential computation selection",
                     setup_compute),
        OPT_BOOLEAN('p', "period", &show_period,
@@ -945,6 +979,7 @@ hpp__entry_pair(struct hist_entry *he, struct hist_entry *pair,
 
        switch (idx) {
        case PERF_HPP_DIFF__DELTA:
+       case PERF_HPP_DIFF__DELTA_ABS:
                if (pair->diff.computed)
                        diff = pair->diff.period_ratio_delta;
                else
@@ -1118,6 +1153,10 @@ static void data__hpp_register(struct data__file *d, int idx)
                fmt->color = hpp__color_wdiff;
                fmt->sort  = hist_entry__cmp_wdiff;
                break;
+       case PERF_HPP_DIFF__DELTA_ABS:
+               fmt->color = hpp__color_delta;
+               fmt->sort  = hist_entry__cmp_delta_abs;
+               break;
        default:
                fmt->sort  = hist_entry__cmp_nop;
                break;
@@ -1195,6 +1234,9 @@ static int ui_init(void)
        case COMPUTE_WEIGHTED_DIFF:
                fmt->sort = hist_entry__cmp_wdiff_idx;
                break;
+       case COMPUTE_DELTA_ABS:
+               fmt->sort = hist_entry__cmp_delta_abs_idx;
+               break;
        default:
                BUG_ON(1);
        }