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)  | 
