diff options
author | Jussi Kivilinna <jussi.kivilinna@iki.fi> | 2023-04-10 20:06:28 +0300 |
---|---|---|
committer | Jussi Kivilinna <jussi.kivilinna@iki.fi> | 2023-04-23 21:19:09 +0300 |
commit | e90fbf6f8dacf280d03e557a65528fc2df24f1d7 (patch) | |
tree | 65618d24c8393949f684e1c9028a29437fd89780 | |
parent | 5d18b401f8a780e2465662e88cbac6974033bf3f (diff) | |
download | libgcrypt-e90fbf6f8dacf280d03e557a65528fc2df24f1d7.tar.gz |
bench-slope: add MPI benchmarking
* 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@iki.fi>
-rw-r--r-- | tests/bench-slope.c | 308 |
1 files changed, 307 insertions, 1 deletions
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); |