[PATCH 1/5] bench-slope: add MPI benchmarking

Jussi Kivilinna jussi.kivilinna at iki.fi
Sat Apr 22 09:35:35 CEST 2023


* tests/bench-slope.c (MPI_START_SIZE, MPI_END_SIZE, MPI_STEP_SIZE)
(MPI_NUM_STEPS, bench_mpi_test, mpi_test_names, bench_mpi_mode)
(bench_mpi_hd, bench_mpi_init, bench_mpi_fre, bench_mpi_do_bench)
(mpi_ops, mpi_modes, mpi_bench_one, _mpi_bench, mpi_match_test)
(mpi_bench): New.
(print_help): Add mention of 'mpi'.
(main): Add "mpi" tests.
--

Patch adds MPI operation benchmarking for bench-slope:

$ tests/bench-slope --cpu-mhz auto mpi
MPI:
                    |  nanosecs/byte   mebibytes/sec   cycles/byte  auto Mhz
 add                |     0.054 ns/B     17580 MiB/s     0.298 c/B      5500
 sub                |     0.083 ns/B     11432 MiB/s     0.459 c/B      5500
 rshift3            |     0.033 ns/B     28862 MiB/s     0.182 c/B      5499
 lshift3            |     0.093 ns/B     10256 MiB/s     0.511 c/B      5500
 rshift65           |     0.096 ns/B      9888 MiB/s     0.530 c/B      5500
 lshift65           |     0.093 ns/B     10228 MiB/s     0.513 c/B      5500
 mul4               |     0.074 ns/B     12825 MiB/s     0.409 c/B      5500
 mul8               |     0.072 ns/B     13313 MiB/s     0.394 c/B      5500
 mul16              |     0.148 ns/B      6450 MiB/s     0.813 c/B      5500
 mul32              |     0.299 ns/B      3191 MiB/s      1.64 c/B      5500
 div4               |     0.458 ns/B      2080 MiB/s      2.52 c/B      5500
 div8               |     0.458 ns/B      2084 MiB/s      2.52 c/B      5500
 div16              |     0.602 ns/B      1584 MiB/s      3.31 c/B      5500
 div32              |     0.926 ns/B      1030 MiB/s      5.09 c/B      5500
 mod4               |     0.443 ns/B      2151 MiB/s      2.44 c/B      5500
 mod8               |     0.443 ns/B      2152 MiB/s      2.44 c/B      5500
 mod16              |     0.600 ns/B      1590 MiB/s      3.30 c/B      5500
 mod32              |     0.924 ns/B      1032 MiB/s      5.08 c/B      5500

Signed-off-by: Jussi Kivilinna <jussi.kivilinna at iki.fi>
---
 tests/bench-slope.c | 308 +++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 307 insertions(+), 1 deletion(-)

diff --git a/tests/bench-slope.c b/tests/bench-slope.c
index f8031e5e..2a203a07 100644
--- a/tests/bench-slope.c
+++ b/tests/bench-slope.c
@@ -2933,13 +2933,310 @@ ecc_bench (char **argv, int argc)
 #endif
 }
 
+/************************************************************ MPI benchmarks. */
+
+#define MPI_START_SIZE 64
+#define MPI_END_SIZE 1024
+#define MPI_STEP_SIZE 8
+#define MPI_NUM_STEPS (((MPI_END_SIZE - MPI_START_SIZE) / MPI_STEP_SIZE) + 1)
+
+enum bench_mpi_test
+{
+  MPI_TEST_ADD = 0,
+  MPI_TEST_SUB,
+  MPI_TEST_RSHIFT3,
+  MPI_TEST_LSHIFT3,
+  MPI_TEST_RSHIFT65,
+  MPI_TEST_LSHIFT65,
+  MPI_TEST_MUL4,
+  MPI_TEST_MUL8,
+  MPI_TEST_MUL16,
+  MPI_TEST_MUL32,
+  MPI_TEST_DIV4,
+  MPI_TEST_DIV8,
+  MPI_TEST_DIV16,
+  MPI_TEST_DIV32,
+  MPI_TEST_MOD4,
+  MPI_TEST_MOD8,
+  MPI_TEST_MOD16,
+  MPI_TEST_MOD32,
+  __MAX_MPI_TEST
+};
+
+static const char * const mpi_test_names[] =
+{
+  "add",
+  "sub",
+  "rshift3",
+  "lshift3",
+  "rshift65",
+  "lshift65",
+  "mul4",
+  "mul8",
+  "mul16",
+  "mul32",
+  "div4",
+  "div8",
+  "div16",
+  "div32",
+  "mod4",
+  "mod8",
+  "mod16",
+  "mod32",
+  NULL,
+};
+
+struct bench_mpi_mode
+{
+  const char *name;
+  struct bench_ops *ops;
+
+  enum bench_mpi_test test_id;
+};
+
+struct bench_mpi_hd
+{
+  gcry_mpi_t bytes[MPI_NUM_STEPS + 1];
+  gcry_mpi_t y;
+};
+
+static int
+bench_mpi_init (struct bench_obj *obj)
+{
+  struct bench_mpi_mode *mode = obj->priv;
+  struct bench_mpi_hd *hd;
+  int y_bytes;
+  int i, j;
+
+  (void)mode;
+
+  obj->min_bufsize = MPI_START_SIZE;
+  obj->max_bufsize = MPI_END_SIZE;
+  obj->step_size = MPI_STEP_SIZE;
+  obj->num_measure_repetitions = num_measurement_repetitions;
+
+  hd = calloc (1, sizeof(*hd));
+  if (!hd)
+    return -1;
+
+  /* Generate input MPIs for benchmark. */
+  for (i = MPI_START_SIZE, j = 0; j < DIM(hd->bytes); i += MPI_STEP_SIZE, j++)
+    {
+      hd->bytes[j] = gcry_mpi_new (i * 8);
+      gcry_mpi_randomize (hd->bytes[j], i * 8, GCRY_WEAK_RANDOM);
+      gcry_mpi_set_bit (hd->bytes[j], i * 8 - 1);
+    }
+
+  switch (mode->test_id)
+    {
+      case MPI_TEST_MUL4:
+      case MPI_TEST_DIV4:
+      case MPI_TEST_MOD4:
+	y_bytes = 4;
+	break;
+
+      case MPI_TEST_MUL8:
+      case MPI_TEST_DIV8:
+      case MPI_TEST_MOD8:
+	y_bytes = 8;
+	break;
+
+      case MPI_TEST_MUL16:
+      case MPI_TEST_DIV16:
+      case MPI_TEST_MOD16:
+	y_bytes = 16;
+	break;
+
+      case MPI_TEST_MUL32:
+      case MPI_TEST_DIV32:
+      case MPI_TEST_MOD32:
+	y_bytes = 32;
+	break;
+
+      default:
+	y_bytes = 0;
+	break;
+    }
+
+  hd->y = gcry_mpi_new (y_bytes * 8);
+  if (y_bytes)
+    {
+      gcry_mpi_randomize (hd->y, y_bytes * 8, GCRY_WEAK_RANDOM);
+      gcry_mpi_set_bit (hd->y, y_bytes * 8 - 1);
+    }
+
+  obj->hd = hd;
+  return 0;
+}
+
+static void
+bench_mpi_free (struct bench_obj *obj)
+{
+  struct bench_mpi_hd *hd = obj->hd;
+  int i;
+
+  gcry_mpi_release (hd->y);
+  for (i = DIM(hd->bytes) - 1; i >= 0; i--)
+    gcry_mpi_release (hd->bytes[i]);
+
+  free(hd);
+}
+
+static void
+bench_mpi_do_bench (struct bench_obj *obj, void *buf, size_t buflen)
+{
+  struct bench_mpi_hd *hd = obj->hd;
+  struct bench_mpi_mode *mode = obj->priv;
+  int bytes_idx = (buflen - MPI_START_SIZE) / MPI_STEP_SIZE;
+  gcry_mpi_t x;
+
+  (void)buf;
+
+  x = gcry_mpi_new (2 * (MPI_END_SIZE + 1) * 8);
+
+  switch (mode->test_id)
+    {
+      case MPI_TEST_ADD:
+	gcry_mpi_add (x, hd->bytes[bytes_idx], hd->bytes[bytes_idx]);
+	break;
+
+      case MPI_TEST_SUB:
+	gcry_mpi_sub (x, hd->bytes[bytes_idx + 1], hd->bytes[bytes_idx]);
+	break;
+
+      case MPI_TEST_RSHIFT3:
+	gcry_mpi_rshift (x, hd->bytes[bytes_idx], 3);
+	break;
+
+      case MPI_TEST_LSHIFT3:
+	gcry_mpi_lshift (x, hd->bytes[bytes_idx], 3);
+	break;
+
+      case MPI_TEST_RSHIFT65:
+	gcry_mpi_rshift (x, hd->bytes[bytes_idx], 65);
+	break;
+
+      case MPI_TEST_LSHIFT65:
+	gcry_mpi_lshift (x, hd->bytes[bytes_idx], 65);
+	break;
+
+      case MPI_TEST_MUL4:
+      case MPI_TEST_MUL8:
+      case MPI_TEST_MUL16:
+      case MPI_TEST_MUL32:
+	gcry_mpi_mul (x, hd->bytes[bytes_idx], hd->y);
+	break;
+
+      case MPI_TEST_DIV4:
+      case MPI_TEST_DIV8:
+      case MPI_TEST_DIV16:
+      case MPI_TEST_DIV32:
+	gcry_mpi_div (x, NULL, hd->bytes[bytes_idx], hd->y, 0);
+	break;
+
+      case MPI_TEST_MOD4:
+      case MPI_TEST_MOD8:
+      case MPI_TEST_MOD16:
+      case MPI_TEST_MOD32:
+	gcry_mpi_mod (x, hd->bytes[bytes_idx], hd->y);
+	break;
+
+      default:
+	break;
+    }
+
+  gcry_mpi_release (x);
+}
+
+static struct bench_ops mpi_ops = {
+  &bench_mpi_init,
+  &bench_mpi_free,
+  &bench_mpi_do_bench
+};
+
+
+static struct bench_mpi_mode mpi_modes[] = {
+  {"", &mpi_ops},
+  {0},
+};
+
+
+static void
+mpi_bench_one (int test_id, struct bench_mpi_mode *pmode)
+{
+  struct bench_mpi_mode mode = *pmode;
+  struct bench_obj obj = { 0 };
+  double result;
+
+  mode.test_id = test_id;
+
+  if (mode.name[0] == '\0')
+    bench_print_algo (-18, mpi_test_names[test_id]);
+  else
+    bench_print_algo (18, mode.name);
+
+  obj.ops = mode.ops;
+  obj.priv = &mode;
+
+  result = do_slope_benchmark (&obj);
+
+  bench_print_result (result);
+}
+
+static void
+_mpi_bench (int test_id)
+{
+  int i;
+
+  for (i = 0; mpi_modes[i].name; i++)
+    mpi_bench_one (test_id, &mpi_modes[i]);
+}
+
+static int
+mpi_match_test(const char *name)
+{
+  int i;
+
+  for (i = 0; i < __MAX_MPI_TEST; i++)
+    if (strcmp(name, mpi_test_names[i]) == 0)
+      return i;
+
+  return -1;
+}
+
+void
+mpi_bench (char **argv, int argc)
+{
+  int i, test_id;
+
+  bench_print_section ("mpi", "MPI");
+  bench_print_header (18, "");
+
+  if (argv && argc)
+    {
+      for (i = 0; i < argc; i++)
+	{
+	  test_id = mpi_match_test (argv[i]);
+	  if (test_id >= 0)
+	    _mpi_bench (test_id);
+	}
+    }
+  else
+    {
+      for (i = 0; i < __MAX_MPI_TEST; i++)
+	_mpi_bench (i);
+    }
+
+  bench_print_footer (18);
+}
+
 /************************************************************** Main program. */
 
 void
 print_help (void)
 {
   static const char *help_lines[] = {
-    "usage: bench-slope [options] [hash|mac|cipher|kdf|ecc [algonames]]",
+    "usage: bench-slope [options] [hash|mac|cipher|kdf|ecc|mpi [algonames]]",
     "",
     " options:",
     "   --cpu-mhz <mhz>           Set CPU speed for calculating cycles",
@@ -3128,6 +3425,7 @@ main (int argc, char **argv)
       cipher_bench (NULL, 0);
       kdf_bench (NULL, 0);
       ecc_bench (NULL, 0);
+      mpi_bench (NULL, 0);
     }
   else if (!strcmp (*argv, "hash"))
     {
@@ -3169,6 +3467,14 @@ main (int argc, char **argv)
       warm_up_cpu ();
       ecc_bench ((argc == 0) ? NULL : argv, argc);
     }
+  else if (!strcmp (*argv, "mpi"))
+    {
+      argc--;
+      argv++;
+
+      warm_up_cpu ();
+      mpi_bench ((argc == 0) ? NULL : argv, argc);
+    }
   else
     {
       fprintf (stderr, PGM ": unknown argument: %s\n", *argv);
-- 
2.39.2




More information about the Gcrypt-devel mailing list