[PATCH 2/9] perf, tools, stat: Support up-scaling of events

From: Andi Kleen
Date: Fri Aug 07 2015 - 21:09:16 EST


From: Andi Kleen <ak@xxxxxxxxxxxxxxx>

TopDown needs to multiply events by constants (for example
the CPU Pipeline Width) to get the correct results.
The kernel needs to export this factor.

Today *.scale is only used to scale down metrics (divide), for example
to scale bytes to MB.

Repurpose negative scale to mean scaling up, that is multiplying.
Implement the code for this in perf stat.

Signed-off-by: Andi Kleen <ak@xxxxxxxxxxxxxxx>
---
tools/perf/builtin-stat.c | 27 +++++++++++++++++++--------
1 file changed, 19 insertions(+), 8 deletions(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index ea5298a..2590c75 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -179,6 +179,17 @@ static inline int nsec_counter(struct perf_evsel *evsel)
return 0;
}

+static double scale_val(struct perf_evsel *counter, u64 val)
+{
+ double uval = val;
+
+ if (counter->scale < 0)
+ uval = val * (-counter->scale);
+ else if (counter->scale)
+ uval = val / counter->scale;
+ return uval;
+}
+
/*
* Read out the results of a single counter:
* do not aggregate counts across CPUs in system-wide mode
@@ -630,12 +641,12 @@ static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)
const char *fmt;

if (csv_output) {
- fmt = sc != 1.0 ? "%.2f%s" : "%.0f%s";
+ fmt = (sc != 1.0 && sc > 0) ? "%.2f%s" : "%.0f%s";
} else {
if (big_num)
- fmt = sc != 1.0 ? "%'18.2f%s" : "%'18.0f%s";
+ fmt = (sc != 1.0 && sc > 0) ? "%'18.2f%s" : "%'18.0f%s";
else
- fmt = sc != 1.0 ? "%18.2f%s" : "%18.0f%s";
+ fmt = (sc != 1.0 && sc > 0) ? "%18.2f%s" : "%18.0f%s";
}

aggr_printout(evsel, id, nr);
@@ -750,7 +761,7 @@ static void aggr_update_shadow(void)
continue;
val += perf_counts(counter->counts, cpu, 0)->val;
}
- val = val * counter->scale;
+ val = scale_val(counter, val);
perf_stat__update_shadow_stats(counter, &val,
first_shadow_cpu(counter, id));
}
@@ -788,7 +799,7 @@ static void print_aggr(char *prefix)
if (prefix)
fprintf(output, "%s", prefix);

- uval = val * counter->scale;
+ uval = scale_val(counter, val);
printout(id, nr, counter, uval, prefix, run, ena, 1.0);
fputc('\n', output);
}
@@ -815,7 +826,7 @@ static void print_aggr_thread(struct perf_evsel *counter, char *prefix)
if (prefix)
fprintf(output, "%s", prefix);

- uval = val * counter->scale;
+ uval = scale_val(counter, val);
printout(thread, 0, counter, uval, prefix, run, ena, 1.0);
fputc('\n', output);
}
@@ -860,7 +871,7 @@ static void print_counter_aggr(struct perf_evsel *counter, char *prefix)
return;
}

- uval = avg * counter->scale;
+ uval = scale_val(counter, avg);
printout(-1, 0, counter, uval, prefix, avg_running, avg_enabled, avg);
fprintf(output, "\n");
}
@@ -884,7 +895,7 @@ static void print_counter(struct perf_evsel *counter, char *prefix)
if (prefix)
fprintf(output, "%s", prefix);

- uval = val * counter->scale;
+ uval = scale_val(counter, val);
printout(cpu, 0, counter, uval, prefix, run, ena, 1.0);

fputc('\n', output);
--
2.4.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/