aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-diff.c
diff options
context:
space:
mode:
authorJiri Olsa <jolsa@redhat.com>2012-10-05 10:44:43 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2012-10-05 13:10:42 -0400
commit81d5f95819953321a2557b0656b24ea10af9629c (patch)
tree27efd993d93ab00da7fdfebe5c3563f1eba4d7f4 /tools/perf/builtin-diff.c
parent96c47f19846742bdfa3c153c8d26ccca5945586b (diff)
perf diff: Add weighted diff computation way to compare hist entries
Adding 'wdiff' as new computation way to compare hist entries. If specified the 'Weighted diff' column is displayed with value 'd' computed as: d = B->period * WEIGHT-A - A->period * WEIGHT-B - A/B being matching hist entry from first/second file specified (or perf.data/perf.data.old) respectively. - period being the hist entry period value - WEIGHT-A/WEIGHT-B being user suplied weights in the the '-c' option behind ':' separator like '-c wdiff:1,2'. Signed-off-by: Jiri Olsa <jolsa@redhat.com> Cc: Andi Kleen <andi@firstfloor.org> Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ingo Molnar <mingo@elte.hu> 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/r/1349448287-18919-5-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/builtin-diff.c')
-rw-r--r--tools/perf/builtin-diff.c116
1 files changed, 111 insertions, 5 deletions
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index e13cfac0b063..d78e8386e1a9 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -27,24 +27,81 @@ static bool show_displacement;
27static bool show_baseline_only; 27static bool show_baseline_only;
28static bool sort_compute; 28static bool sort_compute;
29 29
30static s64 compute_wdiff_w1;
31static s64 compute_wdiff_w2;
32
30enum { 33enum {
31 COMPUTE_DELTA, 34 COMPUTE_DELTA,
32 COMPUTE_RATIO, 35 COMPUTE_RATIO,
36 COMPUTE_WEIGHTED_DIFF,
33 COMPUTE_MAX, 37 COMPUTE_MAX,
34}; 38};
35 39
36const char *compute_names[COMPUTE_MAX] = { 40const char *compute_names[COMPUTE_MAX] = {
37 [COMPUTE_DELTA] = "delta", 41 [COMPUTE_DELTA] = "delta",
38 [COMPUTE_RATIO] = "ratio", 42 [COMPUTE_RATIO] = "ratio",
43 [COMPUTE_WEIGHTED_DIFF] = "wdiff",
39}; 44};
40 45
41static int compute; 46static int compute;
42 47
48static int setup_compute_opt_wdiff(char *opt)
49{
50 char *w1_str = opt;
51 char *w2_str;
52
53 int ret = -EINVAL;
54
55 if (!opt)
56 goto out;
57
58 w2_str = strchr(opt, ',');
59 if (!w2_str)
60 goto out;
61
62 *w2_str++ = 0x0;
63 if (!*w2_str)
64 goto out;
65
66 compute_wdiff_w1 = strtol(w1_str, NULL, 10);
67 compute_wdiff_w2 = strtol(w2_str, NULL, 10);
68
69 if (!compute_wdiff_w1 || !compute_wdiff_w2)
70 goto out;
71
72 pr_debug("compute wdiff w1(%" PRId64 ") w2(%" PRId64 ")\n",
73 compute_wdiff_w1, compute_wdiff_w2);
74
75 ret = 0;
76
77 out:
78 if (ret)
79 pr_err("Failed: wrong weight data, use 'wdiff:w1,w2'\n");
80
81 return ret;
82}
83
84static int setup_compute_opt(char *opt)
85{
86 if (compute == COMPUTE_WEIGHTED_DIFF)
87 return setup_compute_opt_wdiff(opt);
88
89 if (opt) {
90 pr_err("Failed: extra option specified '%s'", opt);
91 return -EINVAL;
92 }
93
94 return 0;
95}
96
43static int setup_compute(const struct option *opt, const char *str, 97static int setup_compute(const struct option *opt, const char *str,
44 int unset __maybe_unused) 98 int unset __maybe_unused)
45{ 99{
46 int *cp = (int *) opt->value; 100 int *cp = (int *) opt->value;
101 char *cstr = (char *) str;
102 char buf[50];
47 unsigned i; 103 unsigned i;
104 char *option;
48 105
49 if (!str) { 106 if (!str) {
50 *cp = COMPUTE_DELTA; 107 *cp = COMPUTE_DELTA;
@@ -53,19 +110,37 @@ static int setup_compute(const struct option *opt, const char *str,
53 110
54 if (*str == '+') { 111 if (*str == '+') {
55 sort_compute = true; 112 sort_compute = true;
56 str++; 113 cstr = (char *) ++str;
57 if (!*str) 114 if (!*str)
58 return 0; 115 return 0;
59 } 116 }
60 117
118 option = strchr(str, ':');
119 if (option) {
120 unsigned len = option++ - str;
121
122 /*
123 * The str data are not writeable, so we need
124 * to use another buffer.
125 */
126
127 /* No option value is longer. */
128 if (len >= sizeof(buf))
129 return -EINVAL;
130
131 strncpy(buf, str, len);
132 buf[len] = 0x0;
133 cstr = buf;
134 }
135
61 for (i = 0; i < COMPUTE_MAX; i++) 136 for (i = 0; i < COMPUTE_MAX; i++)
62 if (!strcmp(str, compute_names[i])) { 137 if (!strcmp(cstr, compute_names[i])) {
63 *cp = i; 138 *cp = i;
64 return 0; 139 return setup_compute_opt(option);
65 } 140 }
66 141
67 pr_err("Failed: '%s' is not computation method " 142 pr_err("Failed: '%s' is not computation method "
68 "(use 'delta' or 'ratio').\n", str); 143 "(use 'delta','ratio' or 'wdiff')\n", str);
69 return -EINVAL; 144 return -EINVAL;
70} 145}
71 146
@@ -97,6 +172,23 @@ double perf_diff__compute_ratio(struct hist_entry *he)
97 return he->diff.period_ratio; 172 return he->diff.period_ratio;
98} 173}
99 174
175s64 perf_diff__compute_wdiff(struct hist_entry *he)
176{
177 struct hist_entry *pair = he->pair;
178 u64 new_period = he->stat.period;
179 u64 old_period = pair ? pair->stat.period : 0;
180
181 he->diff.computed = true;
182
183 if (!pair)
184 he->diff.wdiff = 0;
185 else
186 he->diff.wdiff = new_period * compute_wdiff_w2 -
187 old_period * compute_wdiff_w1;
188
189 return he->diff.wdiff;
190}
191
100static int hists__add_entry(struct hists *self, 192static int hists__add_entry(struct hists *self,
101 struct addr_location *al, u64 period) 193 struct addr_location *al, u64 period)
102{ 194{
@@ -275,6 +367,9 @@ static void hists__precompute(struct hists *hists)
275 case COMPUTE_RATIO: 367 case COMPUTE_RATIO:
276 perf_diff__compute_ratio(he); 368 perf_diff__compute_ratio(he);
277 break; 369 break;
370 case COMPUTE_WEIGHTED_DIFF:
371 perf_diff__compute_wdiff(he);
372 break;
278 default: 373 default:
279 BUG_ON(1); 374 BUG_ON(1);
280 } 375 }
@@ -310,6 +405,13 @@ hist_entry__cmp_compute(struct hist_entry *left, struct hist_entry *right,
310 405
311 return cmp_doubles(l, r); 406 return cmp_doubles(l, r);
312 } 407 }
408 case COMPUTE_WEIGHTED_DIFF:
409 {
410 s64 l = left->diff.wdiff;
411 s64 r = right->diff.wdiff;
412
413 return r - l;
414 }
313 default: 415 default:
314 BUG_ON(1); 416 BUG_ON(1);
315 } 417 }
@@ -434,7 +536,8 @@ static const struct option options[] = {
434 "Show position displacement relative to baseline"), 536 "Show position displacement relative to baseline"),
435 OPT_BOOLEAN('b', "baseline-only", &show_baseline_only, 537 OPT_BOOLEAN('b', "baseline-only", &show_baseline_only,
436 "Show only items with match in baseline"), 538 "Show only items with match in baseline"),
437 OPT_CALLBACK('c', "compute", &compute, "delta,ratio (default delta)", 539 OPT_CALLBACK('c', "compute", &compute,
540 "delta,ratio,wdiff:w1,w2 (default delta)",
438 "Entries differential computation selection", 541 "Entries differential computation selection",
439 setup_compute), 542 setup_compute),
440 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, 543 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
@@ -475,6 +578,9 @@ static void ui_init(void)
475 case COMPUTE_RATIO: 578 case COMPUTE_RATIO:
476 perf_hpp__column_enable(PERF_HPP__RATIO, true); 579 perf_hpp__column_enable(PERF_HPP__RATIO, true);
477 break; 580 break;
581 case COMPUTE_WEIGHTED_DIFF:
582 perf_hpp__column_enable(PERF_HPP__WEIGHTED_DIFF, true);
583 break;
478 default: 584 default:
479 BUG_ON(1); 585 BUG_ON(1);
480 }; 586 };