[igt-dev] [PATCH i-g-t 2/2] lib/i915/perf: break generated code in separate files
Lionel Landwerlin
lionel.g.landwerlin at intel.com
Tue Mar 10 16:29:46 UTC 2020
Initially all the generated code was per generation. Eventually we
grouped it into a single file to reuse as much as possible equation
code (this reduce binary size by a factor). So many equations are just
the same from generation to generation.
But this generated file is 200k lines long...
This change puts all the metrics into a single file and then breaks
down the metric sets per generation.
Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
---
lib/i915/perf-configs/perf-codegen.py | 311 +++++++++++++++++---------
lib/i915/perf.c | 18 +-
lib/meson.build | 21 +-
3 files changed, 241 insertions(+), 109 deletions(-)
diff --git a/lib/i915/perf-configs/perf-codegen.py b/lib/i915/perf-configs/perf-codegen.py
index ac3ad683..e001fc84 100755
--- a/lib/i915/perf-configs/perf-codegen.py
+++ b/lib/i915/perf-configs/perf-codegen.py
@@ -252,33 +252,51 @@ def data_type_to_ctype(ret_type):
def output_counter_read(gen, set, counter):
+ if counter.read_hash in hashed_funcs:
+ return
+
c("\n")
c("/* {0} :: {1} */".format(set.name, counter.get('name')))
+ ret_type = counter.get('data_type')
+ ret_ctype = data_type_to_ctype(ret_type)
+ read_eq = counter.get('equation')
+
+ c(ret_ctype)
+ c(counter.read_sym + "(const struct intel_perf *perf,\n")
+ c.indent(len(counter.read_sym) + 1)
+ c("const struct intel_perf_metric_set *metric_set,\n")
+ c("uint64_t *accumulator)\n")
+ c.outdent(len(counter.read_sym) + 1)
+
+ c("{")
+ c.indent(4)
+
+ output_rpn_equation_code(set, counter, read_eq)
+
+ c.outdent(4)
+ c("}")
+
+ hashed_funcs[counter.read_hash] = counter.read_sym
+
+
+def output_counter_read_definition(gen, set, counter):
if counter.read_hash in hashed_funcs:
- c("#define %s \\" % counter.read_sym)
- c.indent(4)
- c("%s" % hashed_funcs[counter.read_hash])
- c.outdent(4)
+ h("#define %s \\" % counter.read_sym)
+ h.indent(4)
+ h("%s" % hashed_funcs[counter.read_hash])
+ h.outdent(4)
else:
ret_type = counter.get('data_type')
ret_ctype = data_type_to_ctype(ret_type)
read_eq = counter.get('equation')
- c("static " + ret_ctype)
- c(counter.read_sym + "(const struct intel_perf *perf,\n")
- c.indent(len(counter.read_sym) + 1)
- c("const struct intel_perf_metric_set *metric_set,\n")
- c("uint64_t *accumulator)\n")
- c.outdent(len(counter.read_sym) + 1)
-
- c("{")
- c.indent(4)
-
- output_rpn_equation_code(set, counter, read_eq)
-
- c.outdent(4)
- c("}")
+ h(ret_ctype)
+ h(counter.read_sym + "(const struct intel_perf *perf,\n")
+ h.indent(len(counter.read_sym) + 1)
+ h("const struct intel_perf_metric_set *metric_set,\n")
+ h("uint64_t *accumulator);\n")
+ h.outdent(len(counter.read_sym) + 1)
hashed_funcs[counter.read_hash] = counter.read_sym
@@ -289,33 +307,57 @@ def output_counter_max(gen, set, counter):
if not max_eq or max_eq == "100":
return
+ if counter.max_hash in hashed_funcs:
+ return
+
c("\n")
c("/* {0} :: {1} */".format(set.name, counter.get('name')))
+ ret_type = counter.get('data_type')
+ ret_ctype = data_type_to_ctype(ret_type)
+
+ c(ret_ctype)
+ c(counter.max_sym + "(const struct intel_perf *perf,\n")
+ c.indent(len(counter.max_sym) + 1)
+ c("const struct intel_perf_metric_set *metric_set,\n")
+ c("uint64_t *accumulator)\n")
+ c.outdent(len(counter.max_sym) + 1)
+
+ c("{")
+ c.indent(4)
+
+ output_rpn_equation_code(set, counter, max_eq)
+
+ c.outdent(4)
+ c("}")
+
+ hashed_funcs[counter.max_hash] = counter.max_sym
+
+
+def output_counter_max_definition(gen, set, counter):
+ max_eq = counter.get('max_equation')
+
+ if not max_eq or max_eq == "100":
+ return
+
if counter.max_hash in hashed_funcs:
- c("#define %s \\" % counter.max_sym)
- c.indent(4)
- c("%s" % hashed_funcs[counter.max_hash])
- c.outdent(4)
+ h("#define %s \\" % counter.max_sym)
+ h.indent(4)
+ h("%s" % hashed_funcs[counter.max_hash])
+ h.outdent(4)
+ h("\n")
else:
ret_type = counter.get('data_type')
ret_ctype = data_type_to_ctype(ret_type)
- c("static " + ret_ctype)
+ h(ret_ctype)
- c(counter.max_sym + "(const struct intel_perf *perf,\n")
- c.indent(len(counter.max_sym) + 1)
- c("const struct intel_perf_metric_set *metric_set,\n")
- c("uint64_t *accumulator)\n")
- c.outdent(len(counter.max_sym) + 1)
-
- c("{")
- c.indent(4)
-
- output_rpn_equation_code(set, counter, max_eq)
-
- c.outdent(4)
- c("}")
+ h(counter.max_sym + "(const struct intel_perf *perf,")
+ h.indent(len(counter.max_sym) + 1)
+ h("const struct intel_perf_metric_set *metric_set,")
+ h("uint64_t *accumulator);")
+ h.outdent(len(counter.max_sym) + 1)
+ h("\n")
hashed_funcs[counter.max_hash] = counter.max_sym
@@ -524,65 +566,13 @@ class Gen:
self.sets.append(Set(self, xml_set))
-def main():
- global c
- global h
- global xml_equations
+def generate_equations(args, gens):
+ global hashed_funcs
- parser = argparse.ArgumentParser()
- parser.add_argument("--header", help="Header file to write")
- parser.add_argument("--code", help="C file to write")
- parser.add_argument("xml_files", nargs='+', help="List of xml metrics files to process")
-
- args = parser.parse_args()
-
- # Note: either arg may == None
- h = codegen.Codegen(args.header)
- c = codegen.Codegen(args.code)
-
- gens = []
- for xml_file in args.xml_files:
- gens.append(Gen(xml_file))
-
- copyright = textwrap.dedent("""\
- /* Autogenerated file, DO NOT EDIT manually! generated by {}
- *
- * Copyright (c) 2018 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
- """).format(os.path.basename(__file__))
-
- h(copyright)
- c(copyright)
- c(textwrap.dedent("""\
- #include <stddef.h>
- #include <stdint.h>
- #include <stdbool.h>
- #include <assert.h>
-
- """))
-
- c("#include \"" + os.path.basename(args.header) + "\"")
+ header_file = os.path.basename(args.header)
+ header_define = header_file.replace('.', '_').upper()
+ hashed_funcs = {}
c(textwrap.dedent("""\
#include <stdlib.h>
#include <string.h>
@@ -590,11 +580,12 @@ def main():
#include <i915_drm.h>
#include "i915/perf.h"
+ #include "%s"
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
- static double
+ double
percentage_max_callback_float(const struct intel_perf *perf,
const struct intel_perf_metric_set *metric_set,
uint64_t *accumulator)
@@ -602,7 +593,7 @@ def main():
return 100;
}
- static uint64_t
+ uint64_t
percentage_max_callback_uint64(const struct intel_perf *perf,
const struct intel_perf_metric_set *metric_set,
uint64_t *accumulator)
@@ -610,7 +601,7 @@ def main():
return 100;
}
- """))
+ """ % os.path.basename(args.header)))
# Print out all equation functions.
for gen in gens:
@@ -619,6 +610,60 @@ def main():
output_counter_read(gen, set, counter)
output_counter_max(gen, set, counter)
+ hashed_funcs = {}
+ h(textwrap.dedent("""\
+ #ifndef __%s__
+ #define __%s__
+
+ #include <stddef.h>
+ #include <stdint.h>
+ #include <stdbool.h>
+
+ struct intel_perf;
+ struct intel_perf_metric_set;
+
+ double
+ percentage_max_callback_float(const struct intel_perf *perf,
+ const struct intel_perf_metric_set *metric_set,
+ uint64_t *accumulator);
+ uint64_t
+ percentage_max_callback_uint64(const struct intel_perf *perf,
+ const struct intel_perf_metric_set *metric_set,
+ uint64_t *accumulator);
+
+ """ % (header_define, header_define)))
+
+ # Print out all equation functions.
+ for gen in gens:
+ for set in gen.sets:
+ for counter in set.counters:
+ output_counter_read_definition(gen, set, counter)
+ output_counter_max_definition(gen, set, counter)
+
+ h(textwrap.dedent("""\
+
+ #endif /* __%s__ */
+ """ % header_define))
+
+
+def generate_metric_sets(args, gens):
+ header_file = os.path.basename(args.header)
+ header_define = header_file.replace('.', '_').upper()
+
+ c(textwrap.dedent("""\
+ #include <stddef.h>
+ #include <stdint.h>
+ #include <stdlib.h>
+ #include <stdbool.h>
+ #include <assert.h>
+
+ #include "i915_drm.h"
+
+ """))
+
+ c("#include \"{0}\"".format(os.path.basename(args.header)))
+ c("#include \"{0}\"".format(os.path.basename(args.equation_include)))
+
# Print out all set registration functions for each set in each
# generation.
for gen in gens:
@@ -679,15 +724,12 @@ def main():
c("}\n")
h(textwrap.dedent("""\
- #pragma once
+ #ifndef %s
+ #define %s
#include "i915/perf.h"
- #ifdef __cplusplus
- extern "C" {
- #endif
-
- """))
+ """ % (header_define, header_define)))
# Print out all set registration functions for each generation.
for gen in gens:
@@ -705,11 +747,68 @@ def main():
c("}")
h(textwrap.dedent("""\
- #ifdef __cplusplus
- } /* extern C */
- #endif
+ #endif /* %s */
+ """ % header_define))
+
+
+def main():
+ global c
+ global h
+ global xml_equations
+
+ parser = argparse.ArgumentParser()
+ parser.add_argument("--header", help="Header file to write")
+ parser.add_argument("--code", help="C file to write")
+ parser.add_argument("--equations", help="Output equations", action="store_true")
+ parser.add_argument("--metric_sets", help="Output metric sets", action="store_true")
+ parser.add_argument("--equation-include", help="Equation header file")
+ parser.add_argument("xml_files", nargs='+', help="List of xml metrics files to process")
+
+ args = parser.parse_args()
+
+ # Note: either arg may == None
+ h = codegen.Codegen(args.header)
+ c = codegen.Codegen(args.code)
+
+ gens = []
+ for xml_file in args.xml_files:
+ gens.append(Gen(xml_file))
+
+ copyright = textwrap.dedent("""\
+ /* Autogenerated file, DO NOT EDIT manually! generated by {}
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+ """).format(os.path.basename(__file__))
+
+ h(copyright)
+ c(copyright)
+
+ if args.equations:
+ generate_equations(args, gens)
+ if args.metric_sets:
+ generate_metric_sets(args, gens)
- """))
if __name__ == '__main__':
diff --git a/lib/i915/perf.c b/lib/i915/perf.c
index babfe633..8d3e188a 100644
--- a/lib/i915/perf.c
+++ b/lib/i915/perf.c
@@ -37,7 +37,23 @@
#include "intel_chipset.h"
#include "perf.h"
-#include "i915_perf_metrics.h"
+
+#include "i915_perf_metrics_hsw.h"
+#include "i915_perf_metrics_bdw.h"
+#include "i915_perf_metrics_chv.h"
+#include "i915_perf_metrics_sklgt2.h"
+#include "i915_perf_metrics_sklgt3.h"
+#include "i915_perf_metrics_sklgt4.h"
+#include "i915_perf_metrics_kblgt2.h"
+#include "i915_perf_metrics_kblgt3.h"
+#include "i915_perf_metrics_cflgt2.h"
+#include "i915_perf_metrics_cflgt3.h"
+#include "i915_perf_metrics_bxt.h"
+#include "i915_perf_metrics_glk.h"
+#include "i915_perf_metrics_cnl.h"
+#include "i915_perf_metrics_icl.h"
+#include "i915_perf_metrics_ehl.h"
+#include "i915_perf_metrics_tgl.h"
static int
perf_ioctl(int fd, unsigned long request, void *arg)
diff --git a/lib/meson.build b/lib/meson.build
index 8112bec4..f3649615 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -195,16 +195,33 @@ foreach hw : i915_perf_hardware
endforeach
i915_perf_files += custom_target(
- 'i915-perf-metrics',
+ 'i915-perf-equations',
input : i915_xml_files,
- output : [ 'i915_perf_metrics.c', 'i915_perf_metrics.h' ],
+ output : [ 'i915_perf_equations.c', 'i915_perf_equations.h' ],
command : [
find_program('i915/perf-configs/perf-codegen.py'),
'--code', '@OUTPUT0@',
'--header', '@OUTPUT1@',
+ '--equations',
'@INPUT@',
])
+foreach hw : i915_perf_hardware
+ i915_perf_files += custom_target(
+ 'i915-perf-metrics- at 0@'.format(hw),
+ input : 'i915/perf-configs/oa- at 0@.xml'.format(hw),
+ output : [ 'i915_perf_metrics_ at 0@.c'.format(hw),
+ 'i915_perf_metrics_ at 0@.h'.format(hw), ],
+ command : [
+ find_program('i915/perf-configs/perf-codegen.py'),
+ '--code', '@OUTPUT0@',
+ '--header', '@OUTPUT1@',
+ '--metric_sets',
+ '--equation-include', 'i915_perf_equations.h',
+ '@INPUT@',
+ ])
+endforeach
+
lib_igt_i915_perf_build = shared_library(
'i915_perf',
i915_perf_files,
--
2.25.1
More information about the igt-dev
mailing list