diff options
Diffstat (limited to 'tools/perf/builtin-diff.c')
-rw-r--r-- | tools/perf/builtin-diff.c | 80 |
1 files changed, 75 insertions, 5 deletions
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 9ff0db4e2d0c..70a289347591 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -17,6 +17,7 @@ #include "util/symbol.h" #include "util/util.h" #include "util/data.h" +#include "util/config.h" #include <stdlib.h> #include <math.h> @@ -30,6 +31,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 }; @@ -64,7 +66,7 @@ static bool force; static bool show_period; static bool show_formula; static bool show_baseline_only; -static unsigned int sort_compute; +static unsigned int sort_compute = 1; static s64 compute_wdiff_w1; static s64 compute_wdiff_w2; @@ -73,19 +75,22 @@ 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", }; -static int compute; +static int compute = COMPUTE_DELTA_ABS; 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 +116,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 +307,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 +471,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 +509,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 +582,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 @@ -607,6 +625,15 @@ hist_entry__cmp_delta(struct perf_hpp_fmt *fmt, } 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) { @@ -633,6 +660,14 @@ hist_entry__cmp_delta_idx(struct perf_hpp_fmt *fmt __maybe_unused, } 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 +810,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-abs)", "Entries differential computation selection", setup_compute), OPT_BOOLEAN('p', "period", &show_period, @@ -945,6 +980,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 +1154,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,11 +1235,14 @@ 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); } - perf_hpp__register_sort_field(fmt); + perf_hpp__prepend_sort_field(fmt); return 0; } @@ -1249,6 +1292,31 @@ static int data_init(int argc, const char **argv) return 0; } +static int diff__config(const char *var, const char *value, + void *cb __maybe_unused) +{ + if (!strcmp(var, "diff.order")) { + sort_compute = perf_config_int(var, value); + return 0; + } + if (!strcmp(var, "diff.compute")) { + if (!strcmp(value, "delta")) { + compute = COMPUTE_DELTA; + } else if (!strcmp(value, "delta-abs")) { + compute = COMPUTE_DELTA_ABS; + } else if (!strcmp(value, "ratio")) { + compute = COMPUTE_RATIO; + } else if (!strcmp(value, "wdiff")) { + compute = COMPUTE_WEIGHTED_DIFF; + } else { + pr_err("Invalid compute method: %s\n", value); + return -1; + } + } + + return 0; +} + int cmd_diff(int argc, const char **argv, const char *prefix __maybe_unused) { int ret = hists__init(); @@ -1256,6 +1324,8 @@ int cmd_diff(int argc, const char **argv, const char *prefix __maybe_unused) if (ret < 0) return ret; + perf_config(diff__config, NULL); + argc = parse_options(argc, argv, options, diff_usage, 0); if (symbol__init(NULL) < 0) |