perf metricgroup: Scale the metric result
Some metrics define the scale unit, such as { "BriefDescription": "Intel Optane DC persistent memory read latency (ns). Derived from unc_m_pmm_rpq_occupancy.all", "Counter": "0,1,2,3", "EventCode": "0xE0", "EventName": "UNC_M_PMM_READ_LATENCY", "MetricExpr": "UNC_M_PMM_RPQ_OCCUPANCY.ALL / UNC_M_PMM_RPQ_INSERTS / UNC_M_CLOCKTICKS", "MetricName": "UNC_M_PMM_READ_LATENCY", "PerPkg": "1", "ScaleUnit": "6000000000ns", "UMask": "0x1", "Unit": "iMC" }, For above example, the ratio should be, ratio = (UNC_M_PMM_RPQ_OCCUPANCY.ALL / UNC_M_PMM_RPQ_INSERTS / UNC_M_CLOCKTICKS) * 6000000000 But in current code, the ratio is not scaled ( * 6000000000) With this patch, the ratio is scaled and the unit (ns) is printed. For example, # 219.4 ns UNC_M_PMM_READ_LATENCY Signed-off-by: Jin Yao <yao.jin@linux.intel.com> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Andi Kleen <ak@linux.intel.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Kan Liang <kan.liang@linux.intel.com> Cc: Peter Zijlstra <peterz@infradead.org> Link: http://lore.kernel.org/lkml/20190828055932.8269-4-yao.jin@linux.intel.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:

committed by
Arnaldo Carvalho de Melo

parent
a55ab7c4ca
commit
287f2649f7
@@ -87,6 +87,7 @@ struct egroup {
|
|||||||
const char **ids;
|
const char **ids;
|
||||||
const char *metric_name;
|
const char *metric_name;
|
||||||
const char *metric_expr;
|
const char *metric_expr;
|
||||||
|
const char *metric_unit;
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool record_evsel(int *ind, struct evsel **start,
|
static bool record_evsel(int *ind, struct evsel **start,
|
||||||
@@ -182,6 +183,7 @@ static int metricgroup__setup_events(struct list_head *groups,
|
|||||||
}
|
}
|
||||||
expr->metric_expr = eg->metric_expr;
|
expr->metric_expr = eg->metric_expr;
|
||||||
expr->metric_name = eg->metric_name;
|
expr->metric_name = eg->metric_name;
|
||||||
|
expr->metric_unit = eg->metric_unit;
|
||||||
expr->metric_events = metric_events;
|
expr->metric_events = metric_events;
|
||||||
list_add(&expr->nd, &me->head);
|
list_add(&expr->nd, &me->head);
|
||||||
}
|
}
|
||||||
@@ -453,6 +455,7 @@ static int metricgroup__add_metric(const char *metric, struct strbuf *events,
|
|||||||
eg->idnum = idnum;
|
eg->idnum = idnum;
|
||||||
eg->metric_name = pe->metric_name;
|
eg->metric_name = pe->metric_name;
|
||||||
eg->metric_expr = pe->metric_expr;
|
eg->metric_expr = pe->metric_expr;
|
||||||
|
eg->metric_unit = pe->unit;
|
||||||
list_add_tail(&eg->nd, group_list);
|
list_add_tail(&eg->nd, group_list);
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
|
@@ -20,6 +20,7 @@ struct metric_expr {
|
|||||||
struct list_head nd;
|
struct list_head nd;
|
||||||
const char *metric_expr;
|
const char *metric_expr;
|
||||||
const char *metric_name;
|
const char *metric_name;
|
||||||
|
const char *metric_unit;
|
||||||
struct evsel **metric_events;
|
struct evsel **metric_events;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -715,6 +715,7 @@ static void generic_metric(struct perf_stat_config *config,
|
|||||||
struct evsel **metric_events,
|
struct evsel **metric_events,
|
||||||
char *name,
|
char *name,
|
||||||
const char *metric_name,
|
const char *metric_name,
|
||||||
|
const char *metric_unit,
|
||||||
double avg,
|
double avg,
|
||||||
int cpu,
|
int cpu,
|
||||||
struct perf_stat_output_ctx *out,
|
struct perf_stat_output_ctx *out,
|
||||||
@@ -722,7 +723,7 @@ static void generic_metric(struct perf_stat_config *config,
|
|||||||
{
|
{
|
||||||
print_metric_t print_metric = out->print_metric;
|
print_metric_t print_metric = out->print_metric;
|
||||||
struct parse_ctx pctx;
|
struct parse_ctx pctx;
|
||||||
double ratio;
|
double ratio, scale;
|
||||||
int i;
|
int i;
|
||||||
void *ctxp = out->ctx;
|
void *ctxp = out->ctx;
|
||||||
char *n, *pn;
|
char *n, *pn;
|
||||||
@@ -732,7 +733,6 @@ static void generic_metric(struct perf_stat_config *config,
|
|||||||
for (i = 0; metric_events[i]; i++) {
|
for (i = 0; metric_events[i]; i++) {
|
||||||
struct saved_value *v;
|
struct saved_value *v;
|
||||||
struct stats *stats;
|
struct stats *stats;
|
||||||
double scale;
|
|
||||||
|
|
||||||
if (!strcmp(metric_events[i]->name, "duration_time")) {
|
if (!strcmp(metric_events[i]->name, "duration_time")) {
|
||||||
stats = &walltime_nsecs_stats;
|
stats = &walltime_nsecs_stats;
|
||||||
@@ -762,16 +762,32 @@ static void generic_metric(struct perf_stat_config *config,
|
|||||||
if (!metric_events[i]) {
|
if (!metric_events[i]) {
|
||||||
const char *p = metric_expr;
|
const char *p = metric_expr;
|
||||||
|
|
||||||
if (expr__parse(&ratio, &pctx, &p) == 0)
|
if (expr__parse(&ratio, &pctx, &p) == 0) {
|
||||||
print_metric(config, ctxp, NULL, "%8.1f",
|
char *unit;
|
||||||
metric_name ?
|
char metric_bf[64];
|
||||||
metric_name :
|
|
||||||
out->force_header ? name : "",
|
if (metric_unit && metric_name) {
|
||||||
ratio);
|
if (perf_pmu__convert_scale(metric_unit,
|
||||||
else
|
&unit, &scale) >= 0) {
|
||||||
|
ratio *= scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
scnprintf(metric_bf, sizeof(metric_bf),
|
||||||
|
"%s %s", unit, metric_name);
|
||||||
|
print_metric(config, ctxp, NULL, "%8.1f",
|
||||||
|
metric_bf, ratio);
|
||||||
|
} else {
|
||||||
|
print_metric(config, ctxp, NULL, "%8.1f",
|
||||||
|
metric_name ?
|
||||||
|
metric_name :
|
||||||
|
out->force_header ? name : "",
|
||||||
|
ratio);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
print_metric(config, ctxp, NULL, NULL,
|
print_metric(config, ctxp, NULL, NULL,
|
||||||
out->force_header ?
|
out->force_header ?
|
||||||
(metric_name ? metric_name : name) : "", 0);
|
(metric_name ? metric_name : name) : "", 0);
|
||||||
|
}
|
||||||
} else
|
} else
|
||||||
print_metric(config, ctxp, NULL, NULL, "", 0);
|
print_metric(config, ctxp, NULL, NULL, "", 0);
|
||||||
|
|
||||||
@@ -992,7 +1008,7 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config,
|
|||||||
print_metric(config, ctxp, NULL, NULL, name, 0);
|
print_metric(config, ctxp, NULL, NULL, name, 0);
|
||||||
} else if (evsel->metric_expr) {
|
} else if (evsel->metric_expr) {
|
||||||
generic_metric(config, evsel->metric_expr, evsel->metric_events, evsel->name,
|
generic_metric(config, evsel->metric_expr, evsel->metric_events, evsel->name,
|
||||||
evsel->metric_name, avg, cpu, out, st);
|
evsel->metric_name, NULL, avg, cpu, out, st);
|
||||||
} else if (runtime_stat_n(st, STAT_NSECS, 0, cpu) != 0) {
|
} else if (runtime_stat_n(st, STAT_NSECS, 0, cpu) != 0) {
|
||||||
char unit = 'M';
|
char unit = 'M';
|
||||||
char unit_buf[10];
|
char unit_buf[10];
|
||||||
@@ -1021,7 +1037,7 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config,
|
|||||||
out->new_line(config, ctxp);
|
out->new_line(config, ctxp);
|
||||||
generic_metric(config, mexp->metric_expr, mexp->metric_events,
|
generic_metric(config, mexp->metric_expr, mexp->metric_events,
|
||||||
evsel->name, mexp->metric_name,
|
evsel->name, mexp->metric_name,
|
||||||
avg, cpu, out, st);
|
mexp->metric_unit, avg, cpu, out, st);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (num == 0)
|
if (num == 0)
|
||||||
|
Reference in New Issue
Block a user