aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/stat-shadow.c
diff options
context:
space:
mode:
authorAndi Kleen <ak@linux.intel.com>2017-08-31 15:40:31 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2017-09-13 08:49:13 -0400
commitb18f3e365019de1a5b26a851e123f0aedcce881f (patch)
treecad315d132490f8f1018833b8585af2a3d708c5e /tools/perf/util/stat-shadow.c
parentd77ade9f4199c77c63e2ae382a8c8fbe0582ede2 (diff)
perf stat: Support JSON metrics in perf stat
Add generic support for standalone metrics specified in JSON files to perf stat. A metric is a formula that uses multiple events to compute a higher level result (e.g. IPC). Previously metrics were always tied to an event and automatically enabled with that event. But now change it that we can have standalone metrics. They are in the same JSON data structure as events, but don't have an event name. We also allow to organize the metrics in metric groups, which allows a short cut to select several related metrics at once. Add a new -M / --metrics option to perf stat that adds the metrics or metric groups specified. Add the core code to manage and parse the metric groups. They are collected from the JSON data structures into a separate rblist. When computing shadow values look for metrics in that list. Then they are computed using the existing saved values infrastructure in stat-shadow.c The actual JSON metrics are in a separate pull request. % perf stat -M Summary --metric-only -a sleep 1 Performance counter stats for 'system wide': Instructions CLKS CPU_Utilization GFLOPs SMT_2T_Utilization Kernel_Utilization 317614222.0 1392930775.0 0.0 0.0 0.2 0.1 1.001497549 seconds time elapsed % perf stat -M GFLOPs flops Performance counter stats for 'flops': 3,999,541,471 fp_comp_ops_exe.sse_scalar_single # 1.2 GFLOPs (66.65%) 14 fp_comp_ops_exe.sse_scalar_double (66.65%) 0 fp_comp_ops_exe.sse_packed_double (66.67%) 0 fp_comp_ops_exe.sse_packed_single (66.70%) 0 simd_fp_256.packed_double (66.70%) 0 simd_fp_256.packed_single (66.67%) 0 duration_time 3.238372845 seconds time elapsed v2: Add missing header file v3: Move find_map to pmu.c Signed-off-by: Andi Kleen <ak@linux.intel.com> Acked-by: Jiri Olsa <jolsa@kernel.org> Link: http://lkml.kernel.org/r/20170831194036.30146-7-andi@firstfloor.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/stat-shadow.c')
-rw-r--r--tools/perf/util/stat-shadow.c22
1 files changed, 20 insertions, 2 deletions
diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c
index 8c7ab29169b9..42e6c17be7ff 100644
--- a/tools/perf/util/stat-shadow.c
+++ b/tools/perf/util/stat-shadow.c
@@ -6,6 +6,7 @@
6#include "rblist.h" 6#include "rblist.h"
7#include "evlist.h" 7#include "evlist.h"
8#include "expr.h" 8#include "expr.h"
9#include "metricgroup.h"
9 10
10enum { 11enum {
11 CTX_BIT_USER = 1 << 0, 12 CTX_BIT_USER = 1 << 0,
@@ -671,13 +672,16 @@ static void generic_metric(const char *metric_expr,
671 672
672void perf_stat__print_shadow_stats(struct perf_evsel *evsel, 673void perf_stat__print_shadow_stats(struct perf_evsel *evsel,
673 double avg, int cpu, 674 double avg, int cpu,
674 struct perf_stat_output_ctx *out) 675 struct perf_stat_output_ctx *out,
676 struct rblist *metric_events)
675{ 677{
676 void *ctxp = out->ctx; 678 void *ctxp = out->ctx;
677 print_metric_t print_metric = out->print_metric; 679 print_metric_t print_metric = out->print_metric;
678 double total, ratio = 0.0, total2; 680 double total, ratio = 0.0, total2;
679 const char *color = NULL; 681 const char *color = NULL;
680 int ctx = evsel_context(evsel); 682 int ctx = evsel_context(evsel);
683 struct metric_event *me;
684 int num = 1;
681 685
682 if (perf_evsel__match(evsel, HARDWARE, HW_INSTRUCTIONS)) { 686 if (perf_evsel__match(evsel, HARDWARE, HW_INSTRUCTIONS)) {
683 total = avg_stats(&runtime_cycles_stats[ctx][cpu]); 687 total = avg_stats(&runtime_cycles_stats[ctx][cpu]);
@@ -880,6 +884,20 @@ void perf_stat__print_shadow_stats(struct perf_evsel *evsel,
880 } else if (perf_stat_evsel__is(evsel, SMI_NUM)) { 884 } else if (perf_stat_evsel__is(evsel, SMI_NUM)) {
881 print_smi_cost(cpu, evsel, out); 885 print_smi_cost(cpu, evsel, out);
882 } else { 886 } else {
883 print_metric(ctxp, NULL, NULL, NULL, 0); 887 num = 0;
884 } 888 }
889
890 if ((me = metricgroup__lookup(metric_events, evsel, false)) != NULL) {
891 struct metric_expr *mexp;
892
893 list_for_each_entry (mexp, &me->head, nd) {
894 if (num++ > 0)
895 out->new_line(ctxp);
896 generic_metric(mexp->metric_expr, mexp->metric_events,
897 evsel->name, mexp->metric_name,
898 avg, cpu, ctx, out);
899 }
900 }
901 if (num == 0)
902 print_metric(ctxp, NULL, NULL, NULL, 0);
885} 903}