diff options
-rw-r--r-- | tools/perf/Documentation/perf-diff.txt | 33 | ||||
-rw-r--r-- | tools/perf/builtin-diff.c | 52 | ||||
-rw-r--r-- | tools/perf/ui/hist.c | 28 | ||||
-rw-r--r-- | tools/perf/util/hist.h | 1 |
4 files changed, 112 insertions, 2 deletions
diff --git a/tools/perf/Documentation/perf-diff.txt b/tools/perf/Documentation/perf-diff.txt index 6ce95858cd4e..8fff0618c597 100644 --- a/tools/perf/Documentation/perf-diff.txt +++ b/tools/perf/Documentation/perf-diff.txt | |||
@@ -76,6 +76,39 @@ OPTIONS | |||
76 | --baseline-only:: | 76 | --baseline-only:: |
77 | Show only items with match in baseline. | 77 | Show only items with match in baseline. |
78 | 78 | ||
79 | -c:: | ||
80 | --compute:: | ||
81 | Differential computation selection - delta,ratio (default is delta). | ||
82 | See COMPARISON METHODS section for more info. | ||
83 | |||
84 | COMPARISON METHODS | ||
85 | ------------------ | ||
86 | delta | ||
87 | ~~~~~ | ||
88 | If specified the 'Delta' column is displayed with value 'd' computed as: | ||
89 | |||
90 | d = A->period_percent - B->period_percent | ||
91 | |||
92 | with: | ||
93 | - A/B being matching hist entry from first/second file specified | ||
94 | (or perf.data/perf.data.old) respectively. | ||
95 | |||
96 | - period_percent being the % of the hist entry period value within | ||
97 | single data file | ||
98 | |||
99 | ratio | ||
100 | ~~~~~ | ||
101 | If specified the 'Ratio' column is displayed with value 'r' computed as: | ||
102 | |||
103 | r = A->period / B->period | ||
104 | |||
105 | with: | ||
106 | - A/B being matching hist entry from first/second file specified | ||
107 | (or perf.data/perf.data.old) respectively. | ||
108 | |||
109 | - period being the hist entry period value | ||
110 | |||
111 | |||
79 | SEE ALSO | 112 | SEE ALSO |
80 | -------- | 113 | -------- |
81 | linkperf:perf-record[1] | 114 | linkperf:perf-record[1] |
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 1063c31e507c..e90c06aea4d4 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c | |||
@@ -26,6 +26,41 @@ static bool force; | |||
26 | static bool show_displacement; | 26 | static bool show_displacement; |
27 | static bool show_baseline_only; | 27 | static bool show_baseline_only; |
28 | 28 | ||
29 | enum { | ||
30 | COMPUTE_DELTA, | ||
31 | COMPUTE_RATIO, | ||
32 | COMPUTE_MAX, | ||
33 | }; | ||
34 | |||
35 | const char *compute_names[COMPUTE_MAX] = { | ||
36 | [COMPUTE_DELTA] = "delta", | ||
37 | [COMPUTE_RATIO] = "ratio", | ||
38 | }; | ||
39 | |||
40 | static int compute; | ||
41 | |||
42 | static int setup_compute(const struct option *opt, const char *str, | ||
43 | int unset __maybe_unused) | ||
44 | { | ||
45 | int *cp = (int *) opt->value; | ||
46 | unsigned i; | ||
47 | |||
48 | if (!str) { | ||
49 | *cp = COMPUTE_DELTA; | ||
50 | return 0; | ||
51 | } | ||
52 | |||
53 | for (i = 0; i < COMPUTE_MAX; i++) | ||
54 | if (!strcmp(str, compute_names[i])) { | ||
55 | *cp = i; | ||
56 | return 0; | ||
57 | } | ||
58 | |||
59 | pr_err("Failed: '%s' is not computation method " | ||
60 | "(use 'delta' or 'ratio').\n", str); | ||
61 | return -EINVAL; | ||
62 | } | ||
63 | |||
29 | static int hists__add_entry(struct hists *self, | 64 | static int hists__add_entry(struct hists *self, |
30 | struct addr_location *al, u64 period) | 65 | struct addr_location *al, u64 period) |
31 | { | 66 | { |
@@ -262,6 +297,9 @@ static const struct option options[] = { | |||
262 | "Show position displacement relative to baseline"), | 297 | "Show position displacement relative to baseline"), |
263 | OPT_BOOLEAN('b', "baseline-only", &show_baseline_only, | 298 | OPT_BOOLEAN('b', "baseline-only", &show_baseline_only, |
264 | "Show only items with match in baseline"), | 299 | "Show only items with match in baseline"), |
300 | OPT_CALLBACK('c', "compute", &compute, "delta,ratio (default delta)", | ||
301 | "Entries differential computation selection", | ||
302 | setup_compute), | ||
265 | OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, | 303 | OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, |
266 | "dump raw trace in ASCII"), | 304 | "dump raw trace in ASCII"), |
267 | OPT_BOOLEAN('f', "force", &force, "don't complain, do it"), | 305 | OPT_BOOLEAN('f', "force", &force, "don't complain, do it"), |
@@ -290,9 +328,19 @@ static void ui_init(void) | |||
290 | /* No overhead column. */ | 328 | /* No overhead column. */ |
291 | perf_hpp__column_enable(PERF_HPP__OVERHEAD, false); | 329 | perf_hpp__column_enable(PERF_HPP__OVERHEAD, false); |
292 | 330 | ||
293 | /* Display baseline/delta/displacement columns. */ | 331 | /* Display baseline/delta/ratio/displacement columns. */ |
294 | perf_hpp__column_enable(PERF_HPP__BASELINE, true); | 332 | perf_hpp__column_enable(PERF_HPP__BASELINE, true); |
295 | perf_hpp__column_enable(PERF_HPP__DELTA, true); | 333 | |
334 | switch (compute) { | ||
335 | case COMPUTE_DELTA: | ||
336 | perf_hpp__column_enable(PERF_HPP__DELTA, true); | ||
337 | break; | ||
338 | case COMPUTE_RATIO: | ||
339 | perf_hpp__column_enable(PERF_HPP__RATIO, true); | ||
340 | break; | ||
341 | default: | ||
342 | BUG_ON(1); | ||
343 | }; | ||
296 | 344 | ||
297 | if (show_displacement) | 345 | if (show_displacement) |
298 | perf_hpp__column_enable(PERF_HPP__DISPL, true); | 346 | perf_hpp__column_enable(PERF_HPP__DISPL, true); |
diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c index f5a1e4f65263..1b633a4b5c45 100644 --- a/tools/perf/ui/hist.c +++ b/tools/perf/ui/hist.c | |||
@@ -266,6 +266,33 @@ static int hpp__entry_delta(struct perf_hpp *hpp, struct hist_entry *he) | |||
266 | return scnprintf(hpp->buf, hpp->size, fmt, buf); | 266 | return scnprintf(hpp->buf, hpp->size, fmt, buf); |
267 | } | 267 | } |
268 | 268 | ||
269 | static int hpp__header_ratio(struct perf_hpp *hpp) | ||
270 | { | ||
271 | const char *fmt = symbol_conf.field_sep ? "%s" : "%14s"; | ||
272 | |||
273 | return scnprintf(hpp->buf, hpp->size, fmt, "Ratio"); | ||
274 | } | ||
275 | |||
276 | static int hpp__width_ratio(struct perf_hpp *hpp __maybe_unused) | ||
277 | { | ||
278 | return 14; | ||
279 | } | ||
280 | |||
281 | static int hpp__entry_ratio(struct perf_hpp *hpp, struct hist_entry *he) | ||
282 | { | ||
283 | struct hist_entry *pair = he->pair; | ||
284 | double new_period = he->stat.period; | ||
285 | double old_period = pair ? pair->stat.period : 0; | ||
286 | double ratio = pair ? new_period / old_period : 0; | ||
287 | const char *fmt = symbol_conf.field_sep ? "%s" : "%14s"; | ||
288 | char buf[32] = " "; | ||
289 | |||
290 | if (ratio > 0.0) | ||
291 | scnprintf(buf, sizeof(buf), "%+14.6F", ratio); | ||
292 | |||
293 | return scnprintf(hpp->buf, hpp->size, fmt, buf); | ||
294 | } | ||
295 | |||
269 | static int hpp__header_displ(struct perf_hpp *hpp) | 296 | static int hpp__header_displ(struct perf_hpp *hpp) |
270 | { | 297 | { |
271 | return scnprintf(hpp->buf, hpp->size, "Displ."); | 298 | return scnprintf(hpp->buf, hpp->size, "Displ."); |
@@ -311,6 +338,7 @@ struct perf_hpp_fmt perf_hpp__format[] = { | |||
311 | { .cond = false, HPP__PRINT_FNS(samples) }, | 338 | { .cond = false, HPP__PRINT_FNS(samples) }, |
312 | { .cond = false, HPP__PRINT_FNS(period) }, | 339 | { .cond = false, HPP__PRINT_FNS(period) }, |
313 | { .cond = false, HPP__PRINT_FNS(delta) }, | 340 | { .cond = false, HPP__PRINT_FNS(delta) }, |
341 | { .cond = false, HPP__PRINT_FNS(ratio) }, | ||
314 | { .cond = false, HPP__PRINT_FNS(displ) } | 342 | { .cond = false, HPP__PRINT_FNS(displ) } |
315 | }; | 343 | }; |
316 | 344 | ||
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index 66cb31fe81d2..7e4d4c262213 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h | |||
@@ -141,6 +141,7 @@ enum { | |||
141 | PERF_HPP__SAMPLES, | 141 | PERF_HPP__SAMPLES, |
142 | PERF_HPP__PERIOD, | 142 | PERF_HPP__PERIOD, |
143 | PERF_HPP__DELTA, | 143 | PERF_HPP__DELTA, |
144 | PERF_HPP__RATIO, | ||
144 | PERF_HPP__DISPL, | 145 | PERF_HPP__DISPL, |
145 | 146 | ||
146 | PERF_HPP__MAX_INDEX | 147 | PERF_HPP__MAX_INDEX |