From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by gabe.freedesktop.org (Postfix) with ESMTPS id 32DEC6E8B5 for ; Tue, 10 Mar 2020 16:30:05 +0000 (UTC) From: Lionel Landwerlin Date: Tue, 10 Mar 2020 18:29:46 +0200 Message-Id: <20200310162946.2335031-2-lionel.g.landwerlin@intel.com> In-Reply-To: <20200310162946.2335031-1-lionel.g.landwerlin@intel.com> References: <20200310162946.2335031-1-lionel.g.landwerlin@intel.com> MIME-Version: 1.0 Subject: [igt-dev] [PATCH i-g-t 2/2] lib/i915/perf: break generated code in separate files List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: igt-dev-bounces@lists.freedesktop.org Sender: "igt-dev" To: igt-dev@lists.freedesktop.org List-ID: 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 --- 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 - #include - #include - #include - - """)) - - 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 #include @@ -590,11 +580,12 @@ def main(): #include #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 + #include + #include + + 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 + #include + #include + #include + #include + + #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-@0@'.format(hw), + input : 'i915/perf-configs/oa-@0@.xml'.format(hw), + output : [ 'i915_perf_metrics_@0@.c'.format(hw), + 'i915_perf_metrics_@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 _______________________________________________ igt-dev mailing list igt-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/igt-dev