|
@@ -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
|
|
@@ -606,6 +624,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 +659,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 +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,6 +1235,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);
|
|
|
}
|
|
@@ -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)
|