From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1946659AbbHHBGi (ORCPT ); Fri, 7 Aug 2015 21:06:38 -0400 Received: from mga11.intel.com ([192.55.52.93]:32748 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1946516AbbHHBGh (ORCPT ); Fri, 7 Aug 2015 21:06:37 -0400 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.15,632,1432623600"; d="scan'208";a="780041775" From: Andi Kleen To: acme@kernel.org Cc: jolsa@kernel.org, linux-kernel@vger.kernel.org, eranian@google.com, namhyung@kernel.org, peterz@infradead.org, mingo@kernel.org, Andi Kleen Subject: [PATCH 2/9] perf, tools, stat: Support up-scaling of events Date: Fri, 7 Aug 2015 18:06:18 -0700 Message-Id: <1438995985-13631-3-git-send-email-andi@firstfloor.org> X-Mailer: git-send-email 2.4.3 In-Reply-To: <1438995985-13631-1-git-send-email-andi@firstfloor.org> References: <1438995985-13631-1-git-send-email-andi@firstfloor.org> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Andi Kleen 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 --- 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