From: Ville Syrjala <ville.syrjala@linux.intel.com>
To: igt-dev@lists.freedesktop.org
Subject: [igt-dev] [PATCH i-g-t 3/3] lib/i915/perf: Convert the metric counters to an array as well
Date: Mon, 3 Apr 2023 20:48:00 +0300 [thread overview]
Message-ID: <20230403174800.19621-4-ville.syrjala@linux.intel.com> (raw)
In-Reply-To: <20230403174800.19621-1-ville.syrjala@linux.intel.com>
From: Ville Syrjälä <ville.syrjala@linux.intel.com>
The metric counter codegen stuff can also be converted
to chunky arrays to make life easier for the C compiler.
This is more tricky that the register stuff though:
- we have a counter->metric_set backpointer
- the availability needs to be checked for each counter
- intel_perf_add_logical_counter() needs to be called for each counter
So I kept the copy for now, but now we copy from the array
elements instead of populating the thing with code. Could
perhaps get rid of the copy by splitting the counter struct
into const and non-const parts and just pointing to the
array elements instead of copying. But that is left as an
excercise for the reader.
The availability thing I converted to a function pointer.
Might not be ideal since it also prevents putting the array
into .rodata and instead it ends up in .data.rel.ro which
means more work for the dynamic linker. Side note: lambda
would sure be nice to have here...
$ size -A meson-generated_.._i915_perf_metrics_acmgt3.c.o
-.text 1228003 0
+.text 476657 0
+.data.rel.ro 798816 0
And this is the change in build time:
$ touch lib/i915/perf-configs/perf-metricset-codegen.py
$ time ninja -Cbuild -j1
ADL:
- real 0m59,664s
+ real 0m36,788s
VLV:
- real 8m3.277s
+ real 4m1.494s
Cc: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Cc: Umesh Nerlige Ramappa <umesh.nerlige.ramappa@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
.../perf-configs/perf-metricset-codegen.py | 81 ++++++++++++++-----
lib/i915/perf.h | 2 +
2 files changed, 63 insertions(+), 20 deletions(-)
diff --git a/lib/i915/perf-configs/perf-metricset-codegen.py b/lib/i915/perf-configs/perf-metricset-codegen.py
index 8b2c5d7b2e65..57d777bcb13a 100644
--- a/lib/i915/perf-configs/perf-metricset-codegen.py
+++ b/lib/i915/perf-configs/perf-metricset-codegen.py
@@ -39,6 +39,22 @@ semantic_type_map = {
def output_units(unit):
return unit.replace(' ', '_').upper()
+def availability_func_name(set, counter):
+ return set.gen.chipset + "_" + set.underscore_name + "_" + counter.get('symbol_name') + "_availability"
+
+def output_availability_funcs(set, counter):
+ availability = counter.get('availability')
+ if availability:
+ c("static bool " + availability_func_name(set, counter) + "(const struct intel_perf *perf) {")
+ c.indent(4)
+ set.gen.output_availability(set, availability, counter.get('name'))
+ c.indent(4)
+ c("return true;")
+ c.outdent(4)
+ c("}")
+ c("return false;")
+ c.outdent(4)
+ c("}")
def output_counter_report(set, counter):
data_type = counter.get('data_type')
@@ -56,26 +72,22 @@ def output_counter_report(set, counter):
c("\n")
+ c("{")
+ c.indent(4)
+ c(".name = \"{0}\",\n".format(counter.get('name')))
+ c(".symbol_name = \"{0}\",\n".format(counter.get('symbol_name')))
+ c(".desc = \"{0}\",\n".format(counter.get('description')))
+ c(".type = INTEL_PERF_LOGICAL_COUNTER_TYPE_{0},\n".format(semantic_type_uc))
+ c(".storage = INTEL_PERF_LOGICAL_COUNTER_STORAGE_{0},\n".format(data_type_uc))
+ c(".unit = INTEL_PERF_LOGICAL_COUNTER_UNIT_{0},\n".format(output_units(counter.get('units'))))
+ c(".read_{0} = {1},\n".format(data_type, set.read_funcs["$" + counter.get('symbol_name')]))
+ c(".max_{0} = {1},\n".format(data_type, set.max_funcs["$" + counter.get('symbol_name')]))
+ c(".group = \"{0}\",\n".format(counter.get('mdapi_group')))
availability = counter.get('availability')
if availability:
- set.gen.output_availability(set, availability, counter.get('name'))
- c.indent(4)
-
- c("counter = &metric_set->counters[metric_set->n_counters++];\n")
- c("counter->metric_set = metric_set;\n")
- c("counter->name = \"{0}\";\n".format(counter.get('name')))
- c("counter->symbol_name = \"{0}\";\n".format(counter.get('symbol_name')));
- c("counter->desc = \"{0}\";\n".format(counter.get('description')))
- c("counter->type = INTEL_PERF_LOGICAL_COUNTER_TYPE_{0};\n".format(semantic_type_uc))
- c("counter->storage = INTEL_PERF_LOGICAL_COUNTER_STORAGE_{0};\n".format(data_type_uc))
- c("counter->unit = INTEL_PERF_LOGICAL_COUNTER_UNIT_{0};\n".format(output_units(counter.get('units'))))
- c("counter->read_{0} = {1};\n".format(data_type, set.read_funcs["$" + counter.get('symbol_name')]))
- c("counter->max_{0} = {1};\n".format(data_type, set.max_funcs["$" + counter.get('symbol_name')]))
- c("intel_perf_add_logical_counter(perf, counter, \"{0}\");\n".format(counter.get('mdapi_group')))
-
- if availability:
- c.outdent(4)
- c("}\n")
+ c(".availability = {0},\n".format(availability_func_name(set, counter)))
+ c.outdent(4)
+ c("},")
def generate_metric_sets(args, gen):
@@ -97,6 +109,13 @@ def generate_metric_sets(args, gen):
# Print out all set registration functions for each set in each
# generation.
for set in gen.sets:
+ counters = sorted(set.counters, key=lambda k: k.get('symbol_name'))
+
+ c("\n")
+
+ for counter in counters:
+ output_availability_funcs(set, counter)
+
c("\nstatic void\n")
c(gen.chipset + "_add_" + set.underscore_name + "_metric_set(struct intel_perf *perf)")
c("{\n")
@@ -105,8 +124,6 @@ def generate_metric_sets(args, gen):
c("struct intel_perf_metric_set *metric_set;\n")
c("struct intel_perf_logical_counter *counter;\n\n")
- counters = sorted(set.counters, key=lambda k: k.get('symbol_name'))
-
c("metric_set = calloc(1, sizeof(*metric_set));\n")
c("metric_set->name = \"" + set.name + "\";\n")
c("metric_set->symbol_name = \"" + set.symbol_name + "\";\n")
@@ -171,9 +188,31 @@ def generate_metric_sets(args, gen):
c("intel_perf_add_metric_set(perf, metric_set);");
c("\n")
+ c("{")
+ c.indent(4)
+ c("static const struct intel_perf_logical_counter _counters[] = {")
+ c.indent(4)
+
for counter in counters:
output_counter_report(set, counter)
+ c.outdent(4)
+ c("};")
+ c("int i;")
+ c("for (i = 0; i < sizeof(_counters) / sizeof(_counters[0]); i++) {")
+ c.indent(4)
+ c("if (_counters[i].availability && !_counters[i].availability(perf))")
+ c.indent(4)
+ c("continue;")
+ c.outdent(4)
+ c("counter = &metric_set->counters[metric_set->n_counters++];")
+ c("*counter = _counters[i];")
+ c("counter->metric_set = metric_set;")
+ c("intel_perf_add_logical_counter(perf, counter, counter->group);")
+ c.outdent(4)
+ c("}")
+ c.outdent(4)
+ c("}")
c("\nassert(metric_set->n_counters <= {0});\n".format(len(counters)));
c.outdent(4)
@@ -246,6 +285,8 @@ def main():
#ifndef %s
#define %s
+ #include <string.h>
+
#include "i915/perf.h"
""" % (header_define, header_define)))
diff --git a/lib/i915/perf.h b/lib/i915/perf.h
index 6b139f687cca..8a71ac635e78 100644
--- a/lib/i915/perf.h
+++ b/lib/i915/perf.h
@@ -207,6 +207,8 @@ struct intel_perf_logical_counter {
const char *name;
const char *symbol_name;
const char *desc;
+ const char *group;
+ bool (*availability)(const struct intel_perf *perf);
intel_perf_logical_counter_storage_t storage;
intel_perf_logical_counter_type_t type;
intel_perf_logical_counter_unit_t unit;
--
2.39.2
next prev parent reply other threads:[~2023-04-03 17:48 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-04-03 17:47 [igt-dev] [PATCH i-g-t 0/3] lib/i915/perf: Speed up the build Ville Syrjala
2023-04-03 17:47 ` [igt-dev] [PATCH i-g-t 1/3] lib/i915/perf: Stop generating silly C code Ville Syrjala
2023-04-03 17:47 ` [igt-dev] [PATCH i-g-t 2/3] lib/i915/perf: Stop making copies of the registers Ville Syrjala
2023-04-03 17:48 ` Ville Syrjala [this message]
2023-04-03 19:07 ` [igt-dev] ✓ Fi.CI.BAT: success for lib/i915/perf: Speed up the build Patchwork
2023-04-04 1:27 ` [igt-dev] ✓ Fi.CI.IGT: " Patchwork
2023-04-04 7:59 ` [igt-dev] [PATCH i-g-t 0/3] " Lionel Landwerlin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230403174800.19621-4-ville.syrjala@linux.intel.com \
--to=ville.syrjala@linux.intel.com \
--cc=igt-dev@lists.freedesktop.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox