Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Ilya Leoshkevich via Gdb-patches <gdb-patches@sourceware.org>
To: Tom Tromey <tromey@adacore.com>, Andrew Burgess <aburgess@redhat.com>
Cc: Ulrich Weigand <ulrich.weigand@de.ibm.com>,
	Andreas Arnez <arnez@linux.ibm.com>,
	gdb-patches@sourceware.org, Pedro Alves <pedro@palves.net>,
	Ilya Leoshkevich <iii@linux.ibm.com>
Subject: [PATCH v2 7/7] gdb.perf/: Add JIT performance test
Date: Tue, 31 May 2022 00:11:47 +0200	[thread overview]
Message-ID: <20220530221147.1991835-8-iii@linux.ibm.com> (raw)
In-Reply-To: <20220530221147.1991835-1-iii@linux.ibm.com>

The test registers and unregisters 500 functions.  The time it takes to
process each function (the more functions there are, the slower it is)
is written into a global array, which is then read and reported by the
GDB script.
---
 gdb/testsuite/gdb.perf/jit-check.exp | 25 ++++++++
 gdb/testsuite/gdb.perf/jit-check.py  | 60 +++++++++++++++++++
 gdb/testsuite/gdb.perf/jit-solib.c   | 27 +++++++++
 gdb/testsuite/gdb.perf/jit.c         | 87 ++++++++++++++++++++++++++++
 gdb/testsuite/gdb.perf/jit.exp       | 79 +++++++++++++++++++++++++
 5 files changed, 278 insertions(+)
 create mode 100644 gdb/testsuite/gdb.perf/jit-check.exp
 create mode 100644 gdb/testsuite/gdb.perf/jit-check.py
 create mode 100644 gdb/testsuite/gdb.perf/jit-solib.c
 create mode 100644 gdb/testsuite/gdb.perf/jit.c
 create mode 100644 gdb/testsuite/gdb.perf/jit.exp

diff --git a/gdb/testsuite/gdb.perf/jit-check.exp b/gdb/testsuite/gdb.perf/jit-check.exp
new file mode 100644
index 00000000000..c124f294f7b
--- /dev/null
+++ b/gdb/testsuite/gdb.perf/jit-check.exp
@@ -0,0 +1,25 @@
+# Copyright (C) 2022 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Benchmark registering and unregistering JITed code (run part).
+
+load_lib perftest.exp
+load_lib gen-perf-test.exp
+
+if [skip_perf_tests] {
+    return 0
+}
+
+GenPerfTest::standard_run_driver jit.exp make_testcase_config jit-check.py JitCheck
diff --git a/gdb/testsuite/gdb.perf/jit-check.py b/gdb/testsuite/gdb.perf/jit-check.py
new file mode 100644
index 00000000000..c5b46a23ffc
--- /dev/null
+++ b/gdb/testsuite/gdb.perf/jit-check.py
@@ -0,0 +1,60 @@
+# Copyright (C) 2022 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Benchmark for registering and unregistering JITed code.
+
+import os
+import shlex
+
+from perftest import measure
+from perftest import perftest
+from perftest import testresult
+from perftest import utils
+
+
+class JitCheck(perftest.TestCaseWithBasicMeasurements):
+    def __init__(self, name, run_names, binfile):
+        super(JitCheck, self).__init__(name)
+        self.run_names = run_names
+        self.binfile = binfile
+        self.measurement = measure.MeasurementWallTime(
+            testresult.SingleStatisticTestResult()
+        )
+        self.measure.measurements.append(self.measurement)
+
+    def warm_up(self):
+        pass
+
+    def execute_test(self):
+        for run in self.run_names:
+            exe = "{}-{}".format(self.binfile, utils.convert_spaces(run))
+            utils.select_file(exe)
+
+            # Help the binary find the shared objects.
+            pieces = os.path.join(os.path.dirname(exe), "pieces")
+            gdb.execute("cd {}".format(shlex.quote(pieces)))
+
+            # Measure the total run time.
+            utils.runto_main()
+            gdb.execute("tbreak done_breakpoint")
+            self.measure.measure(lambda: gdb.execute("continue"), run)
+
+            # Extract and record processing times for individual functions.
+            for array_name in ("register_times", "unregister_times"):
+                array_value = gdb.parse_and_eval(array_name)
+                for i in range(*array_value.type.range()):
+                    parameter = "{}:{}:{}".format(run, array_name, i + 1)
+                    result = int(array_value[i]) / 1e6
+                    self.measurement.result.record(parameter, result)
diff --git a/gdb/testsuite/gdb.perf/jit-solib.c b/gdb/testsuite/gdb.perf/jit-solib.c
new file mode 100644
index 00000000000..b2f70fc16e8
--- /dev/null
+++ b/gdb/testsuite/gdb.perf/jit-solib.c
@@ -0,0 +1,27 @@
+/* This test program is part of GDB, the GNU debugger.
+
+   Copyright (C) 2022 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* Shared object for benchmarking registering and unregistering JITed code.
+   Must be compiled with -DSHLIB=<shared object number>.  */
+
+#define CAT_1(x, y) x##y
+#define CAT(x, y) CAT_1 (x, y)
+int
+CAT (jited_func_, SHLIB) (void)
+{
+  return SHLIB;
+}
diff --git a/gdb/testsuite/gdb.perf/jit.c b/gdb/testsuite/gdb.perf/jit.c
new file mode 100644
index 00000000000..5fb373a753f
--- /dev/null
+++ b/gdb/testsuite/gdb.perf/jit.c
@@ -0,0 +1,87 @@
+/* This test program is part of GDB, the GNU debugger.
+
+   Copyright (C) 2022 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* Benchmark for registering and unregistering JITed code.
+   Must be compiled with -DTOTAL_NR_SHLIBS=<total number of shared
+   objects>.  */
+
+#include "../gdb.base/jit-elf-util.h"
+#include "../gdb.base/jit-protocol-util.h"
+#include <stdint.h>
+#include <sys/time.h>
+
+static struct jit_code_entry entries[TOTAL_NR_SHLIBS];
+static uint64_t register_times[TOTAL_NR_SHLIBS];
+static uint64_t unregister_times[TOTAL_NR_SHLIBS];
+
+static uint64_t
+time_delta (struct timeval *start_time)
+{
+  struct timeval end_time;
+
+  gettimeofday (&end_time, NULL);
+  return (uint64_t)(end_time.tv_sec - start_time->tv_sec) * 1000000
+	 + (end_time.tv_usec - start_time->tv_usec);
+}
+
+void __attribute__ ((noinline)) done_breakpoint (void) {}
+
+int
+main (void)
+{
+  struct timeval start_time;
+  int i;
+
+  /* Load and register shared libraries.  */
+  for (i = 0; i < TOTAL_NR_SHLIBS; i++)
+    {
+      int (*jited_func) (void);
+      size_t obj_size;
+      char name[32];
+      void *addr;
+
+      sprintf (name, "jit-lib%d.so", i);
+      void *load_addr = n_jit_so_address (i + 1);
+      addr = load_elf (name, &obj_size, load_addr);
+      sprintf (name, "jited_func_%d", i);
+      jited_func = load_symbol (addr, name);
+
+      entries[i].symfile_addr = addr;
+      entries[i].symfile_size = obj_size;
+      gettimeofday (&start_time, NULL);
+      jit_push_back (&entries[i]);
+      register_times[i] = time_delta (&start_time);
+
+      if (jited_func () != i)
+	{
+	  fprintf (stderr, "jited_func_%d () != %d\n", i, i);
+	  return 1;
+	}
+    }
+
+  /* Now unregister them all in reverse order.  */
+  for (i = TOTAL_NR_SHLIBS - 1; i >= 0; i--)
+    {
+      gettimeofday (&start_time, NULL);
+      jit_pop_back ();
+      unregister_times[i] = time_delta (&start_time);
+    }
+
+  done_breakpoint ();
+
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.perf/jit.exp b/gdb/testsuite/gdb.perf/jit.exp
new file mode 100644
index 00000000000..8423312c07a
--- /dev/null
+++ b/gdb/testsuite/gdb.perf/jit.exp
@@ -0,0 +1,79 @@
+# Copyright (C) 2022 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Benchmark registering and unregistering JITed code (build part).
+#
+# Usage example:
+#
+#     make build-perf RUNTESTFLAGS='jit.exp SOLIB_COUNT=100'
+#
+# Supported options:
+#
+# - SOLIB_COUNT: How many shared objects to build (default: 500).
+
+load_lib jit-elf-helpers.exp
+load_lib perftest.exp
+load_lib gen-perf-test.exp
+
+if [skip_perf_tests] {
+    return 0
+}
+
+if ![info exists SOLIB_COUNT] {
+    set SOLIB_COUNT 500
+}
+
+# Adjust binary compile options.
+proc jit_binary_adjust_compile_options { options nr_gen_shlibs } {
+    # Specify shared library load addresses.
+    global jit_compile_options
+    set options [concat $options $jit_compile_options]
+
+    # Specify the total number of shared libraries.
+    lappend options additional_flags=-DTOTAL_NR_SHLIBS=$nr_gen_shlibs
+
+    return $options
+}
+
+# Adjust solib compile options.
+proc jit_solib_adjust_compile_options { options so_nr } {
+    # Disable debuginfo (see compile_and_download_n_jit_so for explanations).
+    set debug [lsearch -exact $options debug]
+    if {$debug != -1} {
+	set options [lreplace $options $debug $debug]
+    }
+
+    # Specify a load address for this solib.
+    lappend options text_segment=[format 0x%x [n_jit_so_address $so_nr]]
+
+    return $options
+}
+
+proc make_testcase_config { } {
+    set program_name "jit"
+    array set testcase [GenPerfTest::init_testcase $program_name]
+    set testcase(language) c
+    set testcase(binary_extra_sources) { { jit.c } }
+    set testcase(binary_link_with_shlibs) { false }
+    set testcase(binary_adjust_compile_options) { jit_binary_adjust_compile_options }
+    set testcase(gen_shlib_extra_sources) { { jit-solib.c } }
+    set testcase(gen_shlib_adjust_compile_options) { jit_solib_adjust_compile_options }
+    set name "${::SOLIB_COUNT}-sos"
+    set testcase(run_names) [list $name]
+    set testcase(nr_gen_shlibs) ${::SOLIB_COUNT}
+    return [array get testcase]
+}
+
+GenPerfTest::standard_compile_driver jit.exp make_testcase_config
-- 
2.35.3


  parent reply	other threads:[~2022-05-30 22:15 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-05-30 22:11 [PATCH v2 0/7] " Ilya Leoshkevich via Gdb-patches
2022-05-30 22:11 ` [PATCH v2 1/7] gdb.perf/: Fix tcl_string_list_to_python_list {x} Ilya Leoshkevich via Gdb-patches
2022-05-30 22:11 ` [PATCH v2 2/7] gdb.perf/: Add binary_link_with_shlibs setting to GenPerfTest Ilya Leoshkevich via Gdb-patches
2022-05-30 22:11 ` [PATCH v2 3/7] gdb.perf/: Allow adjusting GenPerfTest compile options Ilya Leoshkevich via Gdb-patches
2022-05-30 22:11 ` [PATCH v2 4/7] gdb.base/: Introduce jit-protocol-util.h Ilya Leoshkevich via Gdb-patches
2022-05-30 22:11 ` [PATCH v2 5/7] gdb.base/: Introduce jit_compile_options Ilya Leoshkevich via Gdb-patches
2022-05-30 22:11 ` [PATCH v2 6/7] gdb.base/: Introduce n_jit_so_address Ilya Leoshkevich via Gdb-patches
2022-05-30 22:11 ` Ilya Leoshkevich via Gdb-patches [this message]
2022-06-22  8:48 ` [PING] [PATCH v2 0/7] gdb.perf/: Add JIT performance test Ilya Leoshkevich via Gdb-patches
2022-08-03 10:52 ` [PING^2] " Ilya Leoshkevich via Gdb-patches

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=20220530221147.1991835-8-iii@linux.ibm.com \
    --to=gdb-patches@sourceware.org \
    --cc=aburgess@redhat.com \
    --cc=arnez@linux.ibm.com \
    --cc=iii@linux.ibm.com \
    --cc=pedro@palves.net \
    --cc=tromey@adacore.com \
    --cc=ulrich.weigand@de.ibm.com \
    /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