[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