Release 4.14 tools/perf/builtin-diff.c
// SPDX-License-Identifier: GPL-2.0
/*
* builtin-diff.c
*
* Builtin diff command: Analyze two perf.data input files, look up and read
* DSOs and symbol information, sort them and produce a diff.
*/
#include "builtin.h"
#include "util/debug.h"
#include "util/event.h"
#include "util/hist.h"
#include "util/evsel.h"
#include "util/evlist.h"
#include "util/session.h"
#include "util/tool.h"
#include "util/sort.h"
#include "util/symbol.h"
#include "util/util.h"
#include "util/data.h"
#include "util/config.h"
#include <errno.h>
#include <inttypes.h>
#include <stdlib.h>
#include <math.h>
/* Diff command specific HPP columns. */
enum {
PERF_HPP_DIFF__BASELINE,
PERF_HPP_DIFF__PERIOD,
PERF_HPP_DIFF__PERIOD_BASELINE,
PERF_HPP_DIFF__DELTA,
PERF_HPP_DIFF__RATIO,
PERF_HPP_DIFF__WEIGHTED_DIFF,
PERF_HPP_DIFF__FORMULA,
PERF_HPP_DIFF__DELTA_ABS,
PERF_HPP_DIFF__MAX_INDEX
};
struct diff_hpp_fmt {
struct perf_hpp_fmt fmt;
int idx;
char *header;
int header_width;
};
struct data__file {
struct perf_session *session;
struct perf_data_file file;
int idx;
struct hists *hists;
struct diff_hpp_fmt fmt[PERF_HPP_DIFF__MAX_INDEX];
};
static struct data__file *data__files;
static int data__files_cnt;
#define data__for_each_file_start(i, d, s) \
for (i = s, d = &data__files[s]; \
i < data__files_cnt; \
i++, d = &data__files[i])
#define data__for_each_file(i, d) data__for_each_file_start(i, d, 0)
#define data__for_each_file_new(i, d) data__for_each_file_start(i, d, 1)
static bool force;
static bool show_period;
static bool show_formula;
static bool show_baseline_only;
static unsigned int sort_compute = 1;
static s64 compute_wdiff_w1;
static s64 compute_wdiff_w2;
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 = 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,
};
#define MAX_COL_WIDTH 70
static struct header_column {
const char *name;
int width;
} columns[PERF_HPP_DIFF__MAX_INDEX] = {
[PERF_HPP_DIFF__BASELINE] = {
.name = "Baseline",
},
[PERF_HPP_DIFF__PERIOD] = {
.name = "Period",
.width = 14,
},
[PERF_HPP_DIFF__PERIOD_BASELINE] = {
.name = "Base period",
.width = 14,
},
[PERF_HPP_DIFF__DELTA] = {
.name = "Delta",
.width = 7,
},
[PERF_HPP_DIFF__DELTA_ABS] = {
.name = "Delta Abs",
.width = 7,
},
[PERF_HPP_DIFF__RATIO] = {
.name = "Ratio",
.width = 14,
},
[PERF_HPP_DIFF__WEIGHTED_DIFF] = {
.name = "Weighted diff",
.width = 14,
},
[PERF_HPP_DIFF__FORMULA] = {
.name = "Formula",
.width = MAX_COL_WIDTH,
}
};
static int setup_compute_opt_wdiff(char *opt)
{
char *w1_str = opt;
char *w2_str;
int ret = -EINVAL;
if (!opt)
goto out;
w2_str = strchr(opt, ',');
if (!w2_str)
goto out;
*w2_str++ = 0x0;
if (!*w2_str)
goto out;
compute_wdiff_w1 = strtol(w1_str, NULL, 10);
compute_wdiff_w2 = strtol(w2_str, NULL, 10);
if (!compute_wdiff_w1 || !compute_wdiff_w2)
goto out;
pr_debug("compute wdiff w1(%" PRId64 ") w2(%" PRId64 ")\n",
compute_wdiff_w1, compute_wdiff_w2);
ret = 0;
out:
if (ret)
pr_err("Failed: wrong weight data, use 'wdiff:w1,w2'\n");
return ret;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jiri Olsa | 130 | 100.00% | 1 | 100.00% |
Total | 130 | 100.00% | 1 | 100.00% |
static int setup_compute_opt(char *opt)
{
if (compute == COMPUTE_WEIGHTED_DIFF)
return setup_compute_opt_wdiff(opt);
if (opt) {
pr_err("Failed: extra option specified '%s'", opt);
return -EINVAL;
}
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jiri Olsa | 42 | 100.00% | 1 | 100.00% |
Total | 42 | 100.00% | 1 | 100.00% |
static int setup_compute(const struct option *opt, const char *str,
int unset __maybe_unused)
{
int *cp = (int *) opt->value;
char *cstr = (char *) str;
char buf[50];
unsigned i;
char *option;
if (!str) {
*cp = COMPUTE_DELTA;
return 0;
}
option = strchr(str, ':');
if (option) {
unsigned len = option++ - str;
/*
* The str data are not writeable, so we need
* to use another buffer.
*/
/* No option value is longer. */
if (len >= sizeof(buf))
return -EINVAL;
strncpy(buf, str, len);
buf[len] = 0x0;
cstr = buf;
}
for (i = 0; i < COMPUTE_MAX; i++)
if (!strcmp(cstr, compute_names[i])) {
*cp = i;
return setup_compute_opt(option);
}
pr_err("Failed: '%s' is not computation method "
"(use 'delta','ratio' or 'wdiff')\n", str);
return -EINVAL;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jiri Olsa | 180 | 100.00% | 2 | 100.00% |
Total | 180 | 100.00% | 2 | 100.00% |
static double period_percent(struct hist_entry *he, u64 period)
{
u64 total = hists__total_period(he->hists);
return (period * 100.0) / total;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jiri Olsa | 30 | 90.91% | 2 | 66.67% |
Namhyung Kim | 3 | 9.09% | 1 | 33.33% |
Total | 33 | 100.00% | 3 | 100.00% |
static double compute_delta(struct hist_entry *he, struct hist_entry *pair)
{
double old_percent = period_percent(he, he->stat.period);
double new_percent = period_percent(pair, pair->stat.period);
pair->diff.period_ratio_delta = new_percent - old_percent;
pair->diff.computed = true;
return pair->diff.period_ratio_delta;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jiri Olsa | 69 | 100.00% | 4 | 100.00% |
Total | 69 | 100.00% | 4 | 100.00% |
static double compute_ratio(struct hist_entry *he, struct hist_entry *pair)
{
double old_period = he->stat.period ?: 1;
double new_period = pair->stat.period;
pair->diff.computed = true;
pair->diff.period_ratio = new_period / old_period;
return pair->diff.period_ratio;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jiri Olsa | 62 | 100.00% | 4 | 100.00% |
Total | 62 | 100.00% | 4 | 100.00% |
static s64 compute_wdiff(struct hist_entry *he, struct hist_entry *pair)
{
u64 old_period = he->stat.period;
u64 new_period = pair->stat.period;
pair->diff.computed = true;
pair->diff.wdiff = new_period * compute_wdiff_w2 -
old_period * compute_wdiff_w1;
return pair->diff.wdiff;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jiri Olsa | 63 | 100.00% | 4 | 100.00% |
Total | 63 | 100.00% | 4 | 100.00% |
static int formula_delta(struct hist_entry *he, struct hist_entry *pair,
char *buf, size_t size)
{
u64 he_total = he->hists->stats.total_period;
u64 pair_total = pair->hists->stats.total_period;
if (symbol_conf.filter_relative) {
he_total = he->hists->stats.total_non_filtered_period;
pair_total = pair->hists->stats.total_non_filtered_period;
}
return scnprintf(buf, size,
"(%" PRIu64 " * 100 / %" PRIu64 ") - "
"(%" PRIu64 " * 100 / %" PRIu64 ")",
pair->stat.period, pair_total,
he->stat.period, he_total);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jiri Olsa | 56 | 51.85% | 3 | 75.00% |
Namhyung Kim | 52 | 48.15% | 1 | 25.00% |
Total | 108 | 100.00% | 4 | 100.00% |
static int formula_ratio(struct hist_entry *he, struct hist_entry *pair,
char *buf, size_t size)
{
double old_period = he->stat.period;
double new_period = pair->stat.period;
return scnprintf(buf, size, "%.0F / %.0F", new_period, old_period);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jiri Olsa | 55 | 100.00% | 3 | 100.00% |
Total | 55 | 100.00% | 3 | 100.00% |
static int formula_wdiff(struct hist_entry *he, struct hist_entry *pair,
char *buf, size_t size)
{
u64 old_period = he->stat.period;
u64 new_period = pair->stat.period;
return scnprintf(buf, size,
"(%" PRIu64 " * " "%" PRId64 ") - (%" PRIu64 " * " "%" PRId64 ")",
new_period, compute_wdiff_w2, old_period, compute_wdiff_w1);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jiri Olsa | 69 | 100.00% | 3 | 100.00% |
Total | 69 | 100.00% | 3 | 100.00% |
static int formula_fprintf(struct hist_entry *he, struct hist_entry *pair,
char *buf, size_t size)
{
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);
case COMPUTE_WEIGHTED_DIFF:
return formula_wdiff(he, pair, buf, size);
default:
BUG_ON(1);
}
return -1;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jiri Olsa | 84 | 96.55% | 3 | 75.00% |
Namhyung Kim | 3 | 3.45% | 1 | 25.00% |
Total | 87 | 100.00% | 4 | 100.00% |
static int diff__process_sample_event(struct perf_tool *tool __maybe_unused,
union perf_event *event,
struct perf_sample *sample,
struct perf_evsel *evsel,
struct machine *machine)
{
struct addr_location al;
struct hists *hists = evsel__hists(evsel);
int ret = -1;
if (machine__resolve(machine, &al, sample) < 0) {
pr_warning("problem processing %d event, skipping it.\n",
event->header.type);
return -1;
}
if (!hists__add_entry(hists, &al, NULL, NULL, NULL, sample, true)) {
pr_warning("problem incrementing symbol period, skipping event\n");
goto out_put;
}
/*
* The total_period is updated here before going to the output
* tree since normally only the baseline hists will call
* hists__output_resort() and precompute needs the total
* period in order to sort entries by percentage delta.
*/
hists->stats.total_period += sample->period;
if (!al.filtered)
hists->stats.total_non_filtered_period += sample->period;
ret = 0;
out_put:
addr_location__put(&al);
return ret;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Arnaldo Carvalho de Melo | 129 | 82.17% | 14 | 77.78% |
Namhyung Kim | 18 | 11.46% | 2 | 11.11% |
Jiri Olsa | 9 | 5.73% | 1 | 5.56% |
Irina Tirdea | 1 | 0.64% | 1 | 5.56% |
Total | 157 | 100.00% | 18 | 100.00% |
static struct perf_tool tool = {
.sample = diff__process_sample_event,
.mmap = perf_event__process_mmap,
.mmap2 = perf_event__process_mmap2,
.comm = perf_event__process_comm,
.exit = perf_event__process_exit,
.fork = perf_event__process_fork,
.lost = perf_event__process_lost,
.namespaces = perf_event__process_namespaces,
.ordered_events = true,
.ordering_requires_timestamps = true,
};
static struct perf_evsel *evsel_match(struct perf_evsel *evsel,
struct perf_evlist *evlist)
{
struct perf_evsel *e;
evlist__for_each_entry(evlist, e) {
if (perf_evsel__match2(evsel, e))
return e;
}
return NULL;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jiri Olsa | 41 | 89.13% | 1 | 33.33% |
Arnaldo Carvalho de Melo | 5 | 10.87% | 2 | 66.67% |
Total | 46 | 100.00% | 3 | 100.00% |
static void perf_evlist__collapse_resort(struct perf_evlist *evlist)
{
struct perf_evsel *evsel;
evlist__for_each_entry(evlist, evsel) {
struct hists *hists = evsel__hists(evsel);
hists__collapse_resort(hists, NULL);
}
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jiri Olsa | 31 | 75.61% | 1 | 16.67% |
Arnaldo Carvalho de Melo | 6 | 14.63% | 3 | 50.00% |
Namhyung Kim | 4 | 9.76% | 2 | 33.33% |
Total | 41 | 100.00% | 6 | 100.00% |
static struct data__file *fmt_to_data_file(struct perf_hpp_fmt *fmt)
{
struct diff_hpp_fmt *dfmt = container_of(fmt, struct diff_hpp_fmt, fmt);
void *ptr = dfmt - dfmt->idx;
struct data__file *d = container_of(ptr, struct data__file, fmt);
return d;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Namhyung Kim | 56 | 100.00% | 1 | 100.00% |
Total | 56 | 100.00% | 1 | 100.00% |
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;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jiri Olsa | 56 | 100.00% | 1 | 100.00% |
Total | 56 | 100.00% | 1 | 100.00% |
static struct hist_entry*
get_pair_fmt(struct hist_entry *he, struct diff_hpp_fmt *dfmt)
{
struct data__file *d = fmt_to_data_file(&dfmt->fmt);
return get_pair_data(he, d);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jiri Olsa | 35 | 89.74% | 1 | 50.00% |
Namhyung Kim | 4 | 10.26% | 1 | 50.00% |
Total | 39 | 100.00% | 2 | 100.00% |
static void hists__baseline_only(struct hists *hists)
{
struct rb_root *root;
struct rb_node *next;
if (hists__has(hists, need_collapse))
root = &hists->entries_collapsed;
else
root = hists->entries_in;
next = rb_first(root);
while (next != NULL) {
struct hist_entry *he = rb_entry(next, struct hist_entry, rb_node_in);
next = rb_next(&he->rb_node_in);
if (!hist_entry__next_pair(he)) {
rb_erase(&he->rb_node_in, root);
hist_entry__delete(he);
}
}
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jiri Olsa | 75 | 68.81% | 2 | 40.00% |
Namhyung Kim | 30 | 27.52% | 1 | 20.00% |
Arnaldo Carvalho de Melo | 4 | 3.67% | 2 | 40.00% |
Total | 109 | 100.00% | 5 | 100.00% |
static void hists__precompute(struct hists *hists)
{
struct rb_root *root;
struct rb_node *next;
if (hists__has(hists, need_collapse))
root = &hists->entries_collapsed;
else
root = hists->entries_in;
next = rb_first(root);
while (next != NULL) {
struct hist_entry *he, *pair;
struct data__file *d;
int i;
he = rb_entry(next, struct hist_entry, rb_node_in);
next = rb_next(&he->rb_node_in);
data__for_each_file_new(i, d) {
pair = get_pair_data(he, d);
if (!pair)
continue;
switch (compute) {
case COMPUTE_DELTA:
case COMPUTE_DELTA_ABS:
compute_delta(he, pair);
break;
case COMPUTE_RATIO:
compute_ratio(he, pair);
break;
case COMPUTE_WEIGHTED_DIFF:
compute_wdiff(he, pair);
break;
default:
BUG_ON(1);
}
}
}
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jiri Olsa | 148 | 88.10% | 8 | 80.00% |
Namhyung Kim | 20 | 11.90% | 2 | 20.00% |
Total | 168 | 100.00% | 10 | 100.00% |
static int64_t cmp_doubles(double l, double r)
{
if (l > r)
return -1;
else if (l < r)
return 1;
else
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jiri Olsa | 36 | 100.00% | 1 | 100.00% |
Total | 36 | 100.00% | 1 | 100.00% |
static int64_t
__hist_entry__cmp_compute(struct hist_entry *left, struct hist_entry *right,
int c)
{
switch (c) {
case COMPUTE_DELTA:
{
double l = left->diff.period_ratio_delta;
double r = right->diff.period_ratio_delta;
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;
double r = right->diff.period_ratio;
return cmp_doubles(l, r);
}
case COMPUTE_WEIGHTED_DIFF:
{
s64 l = left->diff.wdiff;
s64 r = right->diff.wdiff;
return r - l;
}
default:
BUG_ON(1);
}
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jiri Olsa | 124 | 77.02% | 3 | 75.00% |
Namhyung Kim | 37 | 22.98% | 1 | 25.00% |
Total | 161 | 100.00% | 4 | 100.00% |
static int64_t
hist_entry__cmp_compute(struct hist_entry *left, struct hist_entry *right,
int c, int sort_idx)
{
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_idx]);
p_right = get_pair_data(right, &data__files[sort_idx]);
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);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jiri Olsa | 132 | 96.35% | 1 | 50.00% |
Namhyung Kim | 5 | 3.65% | 1 | 50.00% |
Total | 137 | 100.00% | 2 | 100.00% |
static int64_t
hist_entry__cmp_compute_idx(struct hist_entry *left, struct hist_entry *right,
int c, int sort_idx)
{
struct hist_entry *p_right, *p_left;
p_left = get_pair_data(left, &data__files[sort_idx]);
p_right = get_pair_data(right, &data__files[sort_idx]);
if (!p_left && !p_right)
return 0;
if (!p_left || !p_right)
return p_left ? -1 : 1;
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
* values below.
*/
if (left->dummy && right->dummy)
return 0;
if (left->dummy || right->dummy)
return left->dummy ? 1 : -1;
}
return __hist_entry__cmp_compute(p_left, p_right, c);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Namhyung Kim | 139 | 100.00% | 3 | 100.00% |
Total | 139 | 100.00% | 3 | 100.00% |
static int64_t
hist_entry__cmp_nop(struct perf_hpp_fmt *fmt __maybe_unused,
struct hist_entry *left __maybe_unused,
struct hist_entry *right __maybe_unused)
{
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Namhyung Kim | 27 | 100.00% | 3 | 100.00% |
Total | 27 | 100.00% | 3 | 100.00% |
static int64_t
hist_entry__cmp_baseline(struct perf_hpp_fmt *fmt __maybe_unused,
struct hist_entry *left, struct hist_entry *right)
{
if (left->stat.period == right->stat.period)
return 0;
return left->stat.period > right->stat.period ? 1 : -1;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Namhyung Kim | 57 | 100.00% | 2 | 100.00% |
Total | 57 | 100.00% | 2 | 100.00% |
static int64_t
hist_entry__cmp_delta(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, d->idx);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Namhyung Kim | 45 | 100.00% | 3 | 100.00% |
Total | 45 | 100.00% | 3 | 100.00% |
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);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Namhyung Kim | 45 | 100.00% | 2 | 100.00% |
Total | 45 | 100.00% | 2 | 100.00% |
static int64_t
hist_entry__cmp_ratio(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_RATIO, d->idx);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Namhyung Kim | 45 | 100.00% | 4 | 100.00% |
Total | 45 | 100.00% | 4 | 100.00% |
static int64_t
hist_entry__cmp_wdiff(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_WEIGHTED_DIFF, d->idx);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Namhyung Kim | 45 | 100.00% | 3 | 100.00% |
Total | 45 | 100.00% | 3 | 100.00% |
static int64_t
hist_entry__cmp_delta_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,
sort_compute);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Namhyung Kim | 34 | 100.00% | 1 | 100.00% |
Total | 34 | 100.00% | 1 | 100.00% |
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);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Namhyung Kim | 34 | 100.00% | 2 | 100.00% |
Total | 34 | 100.00% | 2 | 100.00% |
static int64_t
hist_entry__cmp_ratio_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_RATIO,
sort_compute);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Namhyung Kim | 34 | 100.00% | 2 | 100.00% |
Total | 34 | 100.00% | 2 | 100.00% |
static int64_t
hist_entry__cmp_wdiff_idx(struct perf_hpp_fmt *fmt __maybe_unused,
struct hist_entry *left,