Skip to content

Commit

Permalink
perf diff: Add generic order option for compute sorting
Browse files Browse the repository at this point in the history
Adding option 'o' to allow sorting based on the input file number. By
default (without -o option) the output is sorted on baseline.

Also removing '+' sorting support from -c option, because it's not
needed anymore.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/n/tip-l7dvhgt0azm7yiqg3fbn4dxw@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
  • Loading branch information
Jiri Olsa authored and Arnaldo Carvalho de Melo committed Jul 12, 2013
1 parent ef358e6 commit 5f3f8d3
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 31 deletions.
6 changes: 4 additions & 2 deletions tools/perf/Documentation/perf-diff.txt
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,6 @@ OPTIONS
-c::
--compute::
Differential computation selection - delta,ratio,wdiff (default is delta).
If '+' is specified as a first character, the output is sorted based
on the computation results.
See COMPARISON METHODS section for more info.

-p::
Expand All @@ -87,6 +85,10 @@ OPTIONS
--formula::
Show formula for given computation.

-o::
--order::
Specify compute sorting column number.

COMPARISON
----------
The comparison is governed by the baseline file. The baseline perf.data
Expand Down
95 changes: 66 additions & 29 deletions tools/perf/builtin-diff.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ static bool force;
static bool show_period;
static bool show_formula;
static bool show_baseline_only;
static bool sort_compute;
static unsigned int sort_compute;

static s64 compute_wdiff_w1;
static s64 compute_wdiff_w2;
Expand Down Expand Up @@ -188,13 +188,6 @@ static int setup_compute(const struct option *opt, const char *str,
return 0;
}

if (*str == '+') {
sort_compute = true;
cstr = (char *) ++str;
if (!*str)
return 0;
}

option = strchr(str, ':');
if (option) {
unsigned len = option++ - str;
Expand Down Expand Up @@ -378,6 +371,29 @@ static void perf_evlist__collapse_resort(struct perf_evlist *evlist)
}
}

static struct hist_entry*
get_pair_data(struct hist_entry *he, struct data__file *d)
{
if (hist_entry__has_pairs(he)) {
struct hist_entry *pair;

list_for_each_entry(pair, &he->pairs.head, pairs.node)
if (pair->hists == d->hists)
return pair;
}

return NULL;
}

static struct hist_entry*
get_pair_fmt(struct hist_entry *he, struct diff_hpp_fmt *dfmt)
{
void *ptr = dfmt - dfmt->idx;
struct data__file *d = container_of(ptr, struct data__file, fmt);

return get_pair_data(he, d);
}

static void hists__baseline_only(struct hists *hists)
{
struct rb_root *root;
Expand Down Expand Up @@ -412,10 +428,12 @@ static void hists__precompute(struct hists *hists)

next = rb_first(root);
while (next != NULL) {
struct hist_entry *he = rb_entry(next, struct hist_entry, rb_node_in);
struct hist_entry *pair = hist_entry__next_pair(he);
struct hist_entry *he, *pair;

he = rb_entry(next, struct hist_entry, rb_node_in);
next = rb_next(&he->rb_node_in);

pair = get_pair_data(he, &data__files[sort_compute]);
if (!pair)
continue;

Expand Down Expand Up @@ -446,7 +464,7 @@ static int64_t cmp_doubles(double l, double r)
}

static int64_t
hist_entry__cmp_compute(struct hist_entry *left, struct hist_entry *right,
__hist_entry__cmp_compute(struct hist_entry *left, struct hist_entry *right,
int c)
{
switch (c) {
Expand Down Expand Up @@ -478,6 +496,36 @@ hist_entry__cmp_compute(struct hist_entry *left, struct hist_entry *right,
return 0;
}

static int64_t
hist_entry__cmp_compute(struct hist_entry *left, struct hist_entry *right,
int c)
{
bool pairs_left = hist_entry__has_pairs(left);
bool pairs_right = hist_entry__has_pairs(right);
struct hist_entry *p_right, *p_left;

if (!pairs_left && !pairs_right)
return 0;

if (!pairs_left || !pairs_right)
return pairs_left ? -1 : 1;

p_left = get_pair_data(left, &data__files[sort_compute]);
p_right = get_pair_data(right, &data__files[sort_compute]);

if (!p_left && !p_right)
return 0;

if (!p_left || !p_right)
return p_left ? -1 : 1;

/*
* We have 2 entries of same kind, let's
* make the data comparison.
*/
return __hist_entry__cmp_compute(p_left, p_right, c);
}

static void insert_hist_entry_by_compute(struct rb_root *root,
struct hist_entry *he,
int c)
Expand Down Expand Up @@ -680,6 +728,7 @@ static const struct option options[] = {
"columns '.' is reserved."),
OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
"Look for files with symbols relative to this directory"),
OPT_UINTEGER('o', "order", &sort_compute, "Specify compute sorting."),
OPT_END()
};

Expand Down Expand Up @@ -791,28 +840,11 @@ hpp__entry_pair(struct hist_entry *he, struct hist_entry *pair,
};
}

static struct hist_entry *get_pair(struct hist_entry *he,
struct diff_hpp_fmt *dfmt)
{
void *ptr = dfmt - dfmt->idx;
struct data__file *d = container_of(ptr, struct data__file, fmt);

if (hist_entry__has_pairs(he)) {
struct hist_entry *pair;

list_for_each_entry(pair, &he->pairs.head, pairs.node)
if (pair->hists == d->hists)
return pair;
}

return NULL;
}

static void
__hpp__entry_global(struct hist_entry *he, struct diff_hpp_fmt *dfmt,
char *buf, size_t size)
{
struct hist_entry *pair = get_pair(he, dfmt);
struct hist_entry *pair = get_pair_fmt(he, dfmt);
int idx = dfmt->idx;

/* baseline is special */
Expand Down Expand Up @@ -972,6 +1004,11 @@ static int data_init(int argc, const char **argv)
defaults[1] = "perf.data.guest";
}

if (sort_compute >= (unsigned int) data__files_cnt) {
pr_err("Order option out of limit.\n");
return -EINVAL;
}

data__files = zalloc(sizeof(*data__files) * data__files_cnt);
if (!data__files)
return -ENOMEM;
Expand Down

0 comments on commit 5f3f8d3

Please sign in to comment.