From 45bd5668266840d8b2f5f9aa3ed519c66b3c18cb Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Mon, 10 Jun 2024 14:15:18 +0200 Subject: [PATCH] Various perf tools improvements - make it easier to build against OpenSSL 1.1.1 - adjust the test iterations to even out the test runtimes - fix bug in evp_fetch test when running with explicit type --- perf/Makefile | 10 +++++++--- perf/evp_fetch.c | 15 +++++++++------ perf/handshake.c | 14 +++++++++----- perf/newrawkey.c | 17 +++++++++++++---- perf/pkeyread.c | 27 ++++++++++++++++----------- perf/providerdoall.c | 10 +++++++--- perf/randbytes.c | 12 ++++++++---- perf/rsasign.c | 10 +++++++--- perf/sslnew.c | 12 ++++++++---- perf/x509storeissuer.c | 16 ++++++++++------ 10 files changed, 94 insertions(+), 49 deletions(-) diff --git a/perf/Makefile b/perf/Makefile index ed6af31d..78db06b0 100644 --- a/perf/Makefile +++ b/perf/Makefile @@ -1,13 +1,17 @@ all: randbytes handshake sslnew newrawkey rsasign x509storeissuer providerdoall rwlocks pkeyread evp_fetch +# Build target for OpenSSL 1.1.1 builds +all111: randbytes handshake sslnew newrawkey rsasign x509storeissuer rwlocks pkeyread clean: - rm libperf.a *.o randbytes handshake sslnew newrawkey rsasign x509storeissuer providerdoall rwlocks pkeyread evp_fetch - -#-Wl,-rpath,$(TARGET_OSSL_LIBRARY_PATH) + rm -f libperf.a *.o randbytes handshake sslnew newrawkey rsasign x509storeissuer providerdoall rwlocks pkeyread evp_fetch CPPFLAGS += -I$(TARGET_OSSL_INCLUDE_PATH) -I. +# For second include path, i.e. out of tree build of OpenSSL uncomment this: +# CPPFLAGS += -I$(TARGET_OSSL_INCLUDE_PATH2) CFLAGS += -pthread LDFLAGS += -L$(TARGET_OSSL_LIBRARY_PATH) -L. +# For setting RUNPATH on built executables uncomment this: +# LDFLAGS += -Wl,-rpath,$(TARGET_OSSL_LIBRARY_PATH) libperf.a: perflib/*.c perflib/*.h $(CC) $(CPPFLAGS) $(CFLAGS) -c perflib/*.c diff --git a/perf/evp_fetch.c b/perf/evp_fetch.c index 6cd90648..e092e5bc 100644 --- a/perf/evp_fetch.c +++ b/perf/evp_fetch.c @@ -15,13 +15,14 @@ #include #include "perflib/perflib.h" -#define NUM_CALLS_PER_TEST 1000000 +#define NUM_CALLS_PER_TEST 10000000 OSSL_TIME *times; int err = 0; static int threadcount; +size_t num_calls; static OSSL_LIB_CTX *ctx = NULL; @@ -96,13 +97,14 @@ void do_fetch(size_t num) start = ossl_time_now(); - for (i = 0; i < NUM_CALLS_PER_TEST / threadcount; i++) { + for (i = 0; i < num_calls / threadcount; i++) { /* * If we set a fetch type, always use that */ if (exclusive_fetch_type == FETCH_END) { j = i % ARRAY_SIZE(fetch_entries); fetch_alg = fetch_entries[j].alg; + j = fetch_entries[j].ftype; } else { j = exclusive_fetch_type; fetch_alg = exclusive_fetch_alg; @@ -111,7 +113,7 @@ void do_fetch(size_t num) if (err == 1) return; - switch (fetch_entries[j].ftype) { + switch (j) { case FETCH_MD: { EVP_MD *md = EVP_MD_fetch(ctx, fetch_alg, fetch_entries[j].propq); @@ -180,7 +182,6 @@ int main(int argc, char *argv[]) { OSSL_TIME duration; OSSL_TIME ttime; - double real_num_calls; double av; int terse = 0; int argnext; @@ -227,6 +228,9 @@ int main(int argc, char *argv[]) printf("threadcount must be > 0\n"); return EXIT_FAILURE; } + num_calls = NUM_CALLS_PER_TEST; + if (NUM_CALLS_PER_TEST % threadcount > 0) /* round up */ + num_calls += threadcount - NUM_CALLS_PER_TEST % threadcount; ctx = OSSL_LIB_CTX_new(); if (ctx == NULL) @@ -260,8 +264,7 @@ int main(int argc, char *argv[]) * zero in the math. Instead, manually do the division, casting * our values as doubles so that we compute the proper time */ - real_num_calls = ((double)NUM_CALLS_PER_TEST / threadcount) * threadcount; - av = ((double)ossl_time2ticks(ttime) / real_num_calls) /(double)OSSL_TIME_US; + av = ((double)ossl_time2ticks(ttime) / num_calls) /(double)OSSL_TIME_US; if (terse) printf("%lf\n", av); diff --git a/perf/handshake.c b/perf/handshake.c index 2f699c6d..89526d03 100644 --- a/perf/handshake.c +++ b/perf/handshake.c @@ -14,7 +14,7 @@ #include #include "perflib/perflib.h" -#define NUM_HANDSHAKES_PER_RUN 100000 +#define NUM_CALLS_PER_TEST 10000 int err = 0; @@ -26,12 +26,13 @@ static char *privkey = NULL; OSSL_TIME *times; static int threadcount; +size_t num_calls; static void do_handshake(size_t num) { SSL *clientssl = NULL, *serverssl = NULL; int ret = 1; - int i; + size_t i; OSSL_TIME start, end; SSL_CTX *lsctx = NULL; SSL_CTX *lcctx = NULL; @@ -43,7 +44,7 @@ static void do_handshake(size_t num) start = ossl_time_now(); - for (i = 0; i < NUM_HANDSHAKES_PER_RUN / threadcount; i++) { + for (i = 0; i < num_calls / threadcount; i++) { if (share_ctx == 0) { if (!perflib_create_ssl_ctx_pair(TLS_server_method(), TLS_client_method(), @@ -116,6 +117,9 @@ int main(int argc, char *argv[]) printf("threadcount must be > 0\n"); goto err; } + num_calls = NUM_CALLS_PER_TEST; + if (NUM_CALLS_PER_TEST % threadcount > 0) /* round up */ + num_calls += threadcount - NUM_CALLS_PER_TEST % threadcount; times = OPENSSL_malloc(sizeof(OSSL_TIME) * threadcount); if (times == NULL) { @@ -145,8 +149,8 @@ int main(int argc, char *argv[]) for (i = 1; i < threadcount; i++) ttime = ossl_time_add(ttime, times[i]); - avcalltime = ((double)ossl_time2ticks(ttime) / (double)NUM_HANDSHAKES_PER_RUN) / (double)OSSL_TIME_US; - persec = ((NUM_HANDSHAKES_PER_RUN * OSSL_TIME_SECOND) + avcalltime = ((double)ossl_time2ticks(ttime) / num_calls) / (double)OSSL_TIME_US; + persec = ((num_calls * OSSL_TIME_SECOND) / (double)ossl_time2ticks(duration)); if (terse) { diff --git a/perf/newrawkey.c b/perf/newrawkey.c index d701ece1..a19be252 100644 --- a/perf/newrawkey.c +++ b/perf/newrawkey.c @@ -13,8 +13,9 @@ #include #include "perflib/perflib.h" -#define NUM_CALLS_PER_TEST 100000 +#define NUM_CALLS_PER_TEST 1000000 +size_t num_calls; OSSL_TIME *times; int err = 0; @@ -29,15 +30,20 @@ static int threadcount; void do_newrawkey(size_t num) { - int i; + size_t i; EVP_PKEY *pkey; OSSL_TIME start, end; start = ossl_time_now(); - for (i = 0; i < NUM_CALLS_PER_TEST / threadcount; i++) { + for (i = 0; i < num_calls / threadcount; i++) { +#if OPENSSL_VERSION_NUMBER >= 0x30000000L pkey = EVP_PKEY_new_raw_public_key_ex(NULL, "X25519", NULL, buf, sizeof(buf)); +#else + pkey = EVP_PKEY_new_raw_public_key(EVP_PKEY_X25519, NULL, buf, + sizeof(buf)); +#endif if (pkey == NULL) err = 1; else @@ -76,6 +82,9 @@ int main(int argc, char *argv[]) printf("threadcount must be > 0\n"); return EXIT_FAILURE; } + num_calls = NUM_CALLS_PER_TEST; + if (NUM_CALLS_PER_TEST % threadcount > 0) /* round up */ + num_calls += threadcount - NUM_CALLS_PER_TEST % threadcount; times = OPENSSL_malloc(sizeof(OSSL_TIME) * threadcount); if (times == NULL) { @@ -105,7 +114,7 @@ int main(int argc, char *argv[]) * zero in the math. Instead, manually do the division, casting * our values as doubles so that we compute the proper time */ - av = ((double)ossl_time2ticks(ttime) / (double)NUM_CALLS_PER_TEST) /(double)OSSL_TIME_US; + av = ((double)ossl_time2ticks(ttime) / num_calls) /(double)OSSL_TIME_US; if (terse) printf("%lf\n", av); diff --git a/perf/pkeyread.c b/perf/pkeyread.c index 2b9fe5c1..e16569d7 100644 --- a/perf/pkeyread.c +++ b/perf/pkeyread.c @@ -20,8 +20,9 @@ /* run 'make regen_key_samples' if header file is missing */ #include "keys.h" -#define NUM_CALLS_PER_TEST 100000 +#define NUM_CALLS_PER_TEST 10000 +size_t num_calls; static OSSL_TIME *times = NULL; int err = 0; @@ -36,7 +37,7 @@ static void do_pemread(size_t num) size_t keydata_sz; EVP_PKEY *key; BIO *pem; - int i; + size_t i; size_t len; OSSL_TIME start, end; @@ -63,10 +64,11 @@ static void do_pemread(size_t num) * Technically this includes the EVP_PKEY_free() in the timing - but I * think we can live with that */ - for (i = 0; i < NUM_CALLS_PER_TEST / threadcount; i++) { + for (i = 0; i < num_calls / threadcount; i++) { key = PEM_read_bio_PrivateKey(pem, NULL, NULL, NULL); if (key == NULL) { - fprintf(stderr, "Failed to create key: %d [%s PEM]\n", i, + fprintf(stderr, "Failed to create key: %llu [%s PEM]\n", + (unsigned long long)i, sample_names[sample_id]); err = 1; BIO_free(pem); @@ -111,13 +113,13 @@ static void do_derread(size_t num) start = ossl_time_now(); - for (i = 0; i < NUM_CALLS_PER_TEST / threadcount && err == 0; i++) { - keydata = (const unsigned char *)sample_keys[sample_id][FORMAT_DER]; - keydata_sz = sample_key_sizes[sample_id][FORMAT_DER]; - pkey = d2i_PrivateKey_ex(sample_id_to_evp(sample_id), NULL, - &keydata, keydata_sz, NULL, NULL); + for (i = 0; i < num_calls / threadcount && err == 0; i++) { + keydata = (const unsigned char *)sample_keys[sample_id][FORMAT_DER]; + keydata_sz = sample_key_sizes[sample_id][FORMAT_DER]; + pkey = d2i_PrivateKey(sample_id_to_evp(sample_id), NULL, + &keydata, keydata_sz); if (pkey == NULL) { - fprintf(stderr, "%s pkey is NULL [%s BER]\n", + fprintf(stderr, "%s pkey is NULL [%s DER]\n", __func__, sample_names[sample_id]); err = 1; goto error; @@ -166,7 +168,7 @@ static double get_avcalltime(void) memset(&t, 0, sizeof(t)); for (i = 0; i < threadcount; i++) t = ossl_time_add(t, times[i]); - avcalltime = (double)ossl_time2ticks(t) / (double)NUM_CALLS_PER_TEST; + avcalltime = (double)ossl_time2ticks(t) / num_calls; avcalltime = avcalltime / (double)OSSL_TIME_US; @@ -264,6 +266,9 @@ int main(int argc, char *argv[]) fprintf(stderr, "threadcount must be > 0, use option -t 1\n"); return EXIT_FAILURE; } + num_calls = NUM_CALLS_PER_TEST; + if (NUM_CALLS_PER_TEST % threadcount > 0) /* round up */ + num_calls += threadcount - NUM_CALLS_PER_TEST % threadcount; times = OPENSSL_malloc(sizeof(OSSL_TIME) * threadcount); if (times == NULL) { diff --git a/perf/providerdoall.c b/perf/providerdoall.c index e2aec1d1..419160fb 100644 --- a/perf/providerdoall.c +++ b/perf/providerdoall.c @@ -17,6 +17,7 @@ #define NUM_CALLS_PER_TEST 100000 +size_t num_calls; static int err = 0; OSSL_TIME *times; @@ -32,14 +33,14 @@ static int threadcount; static void do_providerdoall(size_t num) { - int i; + size_t i; unsigned char buf[32]; int count; OSSL_TIME start, end; start = ossl_time_now(); - for (i = 0; i < NUM_CALLS_PER_TEST / threadcount; i++) { + for (i = 0; i < num_calls / threadcount; i++) { count = 0; if (!OSSL_PROVIDER_do_all(NULL, doit, &count) || count != 1) { err = 1; @@ -78,6 +79,9 @@ int main(int argc, char *argv[]) printf("threadcount must be > 0\n"); return EXIT_FAILURE; } + num_calls = NUM_CALLS_PER_TEST; + if (NUM_CALLS_PER_TEST % threadcount > 0) /* round up */ + num_calls += threadcount - NUM_CALLS_PER_TEST % threadcount; times = OPENSSL_malloc(sizeof(OSSL_TIME) * threadcount); if (times == NULL) { @@ -99,7 +103,7 @@ int main(int argc, char *argv[]) for (i = 1; i < threadcount; i++) ttime = ossl_time_add(ttime, times[i]); - av = ((double)ossl_time2ticks(ttime) / (double)NUM_CALLS_PER_TEST) / (double)OSSL_TIME_US; + av = ((double)ossl_time2ticks(ttime) / num_calls) / (double)OSSL_TIME_US; if (terse) printf("%lf\n", av); diff --git a/perf/randbytes.c b/perf/randbytes.c index e57fe3ea..e8f5bb23 100644 --- a/perf/randbytes.c +++ b/perf/randbytes.c @@ -14,8 +14,9 @@ #include #include "perflib/perflib.h" -#define NUM_CALLS_PER_TEST 100000 +#define NUM_CALLS_PER_TEST 1000000 +size_t num_calls; OSSL_TIME *times = NULL; int err = 0; @@ -24,13 +25,13 @@ static int threadcount; void do_randbytes(size_t num) { - int i; + size_t i; unsigned char buf[32]; OSSL_TIME start, end; start = ossl_time_now(); - for (i = 0; i < NUM_CALLS_PER_TEST / threadcount; i++) + for (i = 0; i < num_calls / threadcount; i++) if (!RAND_bytes(buf, sizeof(buf))) err = 1; @@ -66,6 +67,9 @@ int main(int argc, char *argv[]) printf("threadcount must be > 0\n"); return EXIT_FAILURE; } + num_calls = NUM_CALLS_PER_TEST; + if (NUM_CALLS_PER_TEST % threadcount > 0) /* round up */ + num_calls += threadcount - NUM_CALLS_PER_TEST % threadcount; times = OPENSSL_malloc(sizeof(OSSL_TIME) * threadcount); if (times == NULL) { @@ -87,7 +91,7 @@ int main(int argc, char *argv[]) for (i = 1; i < threadcount; i++) ttime = ossl_time_add(ttime, times[i]); - avcalltime = ((double)ossl_time2ticks(ttime) / (double)NUM_CALLS_PER_TEST) /(double)OSSL_TIME_US; + avcalltime = ((double)ossl_time2ticks(ttime) / num_calls) /(double)OSSL_TIME_US; if (terse) printf("%lf\n", avcalltime); diff --git a/perf/rsasign.c b/perf/rsasign.c index 3cc6d218..db8405a3 100644 --- a/perf/rsasign.c +++ b/perf/rsasign.c @@ -18,6 +18,7 @@ #define NUM_CALLS_PER_TEST 100000 +size_t num_calls; int err = 0; EVP_PKEY *rsakey = NULL; @@ -41,7 +42,7 @@ static OSSL_TIME *times = NULL; void do_rsasign(size_t num) { - int i; + size_t i; unsigned char buf[32]; unsigned char sig[64]; EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(rsakey, NULL); @@ -50,7 +51,7 @@ void do_rsasign(size_t num) start = ossl_time_now(); - for (i = 0; i < NUM_CALLS_PER_TEST / threadcount; i++) { + for (i = 0; i < num_calls / threadcount; i++) { if (EVP_PKEY_sign_init(ctx) <= 0 || EVP_PKEY_sign(ctx, sig, &siglen, tbs, SHA_DIGEST_LENGTH) <= 0) { err = 1; @@ -93,6 +94,9 @@ int main(int argc, char *argv[]) printf("threadcount must be > 0\n"); return EXIT_FAILURE; } + num_calls = NUM_CALLS_PER_TEST; + if (NUM_CALLS_PER_TEST % threadcount > 0) /* round up */ + num_calls += threadcount - NUM_CALLS_PER_TEST % threadcount; assert(strlen(tbs) == SHA_DIGEST_LENGTH); membio = BIO_new_mem_buf(rsakeypem, strlen(rsakeypem)); @@ -127,7 +131,7 @@ int main(int argc, char *argv[]) for (i = 1; i < threadcount; i++) ttime = ossl_time_add(ttime, times[i]); - avcalltime = ((double)ossl_time2ticks(ttime) / (double)NUM_CALLS_PER_TEST) / (double)OSSL_TIME_US; + avcalltime = ((double)ossl_time2ticks(ttime) / num_calls) / (double)OSSL_TIME_US; if (terse) printf("%lf\n", avcalltime); diff --git a/perf/sslnew.c b/perf/sslnew.c index d665b52e..c65f55db 100644 --- a/perf/sslnew.c +++ b/perf/sslnew.c @@ -14,24 +14,25 @@ #include #include "perflib/perflib.h" -#define NUM_CALLS_PER_TEST 100000 +#define NUM_CALLS_PER_TEST 1000000 int err = 0; static SSL_CTX *ctx; +size_t num_calls; static int threadcount; static OSSL_TIME *times = NULL; void do_sslnew(size_t num) { - int i; + size_t i; SSL *s; BIO *rbio, *wbio; OSSL_TIME start, end; start = ossl_time_now(); - for (i = 0; i < NUM_CALLS_PER_TEST / threadcount; i++) { + for (i = 0; i < num_calls / threadcount; i++) { s = SSL_new(ctx); rbio = BIO_new(BIO_s_mem()); wbio = BIO_new(BIO_s_mem()); @@ -80,6 +81,9 @@ int main(int argc, char *argv[]) printf("threadcount must be > 0\n"); return EXIT_FAILURE; } + num_calls = NUM_CALLS_PER_TEST; + if (NUM_CALLS_PER_TEST % threadcount > 0) /* round up */ + num_calls += threadcount - NUM_CALLS_PER_TEST % threadcount; times = OPENSSL_malloc(sizeof(OSSL_TIME) * threadcount); if (times == NULL) { @@ -107,7 +111,7 @@ int main(int argc, char *argv[]) for (i = 1; i < threadcount; i++) ttime = ossl_time_add(ttime, times[i]); - avcalltime = ((double)ossl_time2ticks(ttime) / (double)NUM_CALLS_PER_TEST) / (double)OSSL_TIME_US; + avcalltime = ((double)ossl_time2ticks(ttime) / num_calls) / (double)OSSL_TIME_US; if (terse) printf("%lf\n", avcalltime); diff --git a/perf/x509storeissuer.c b/perf/x509storeissuer.c index 4cfff6af..102e4266 100644 --- a/perf/x509storeissuer.c +++ b/perf/x509storeissuer.c @@ -14,18 +14,19 @@ #include #include "perflib/perflib.h" -#define NUM_CALLS_PER_TEST 100000 +#define NUM_CALLS_PER_TEST 1000000 static int err = 0; static X509_STORE *store = NULL; static X509 *x509 = NULL; +size_t num_calls; OSSL_TIME *times; static int threadcount; static void do_x509storeissuer(size_t num) { - int i; + size_t i; X509_STORE_CTX *ctx = X509_STORE_CTX_new(); X509 *issuer = NULL; OSSL_TIME start, end; @@ -38,7 +39,7 @@ static void do_x509storeissuer(size_t num) start = ossl_time_now(); - for (i = 0; i < NUM_CALLS_PER_TEST / threadcount; i++) { + for (i = 0; i < num_calls / threadcount; i++) { /* * We actually expect this to fail. We've not configured any * certificates inside our store. We're just testing calling this @@ -67,9 +68,9 @@ int main(int argc, char *argv[]) double avcalltime; int terse = 0; int argnext; - char *cert; + char *cert = NULL; int ret = EXIT_FAILURE; - BIO *bio; + BIO *bio = NULL; if ((argc != 3 && argc != 4) || (argc == 4 && strcmp("--terse", argv[1]) != 0)) { @@ -95,6 +96,9 @@ int main(int argc, char *argv[]) printf("threadcount must be > 0\n"); goto err; } + num_calls = NUM_CALLS_PER_TEST; + if (NUM_CALLS_PER_TEST % threadcount > 0) /* round up */ + num_calls += threadcount - NUM_CALLS_PER_TEST % threadcount; store = X509_STORE_new(); if (store == NULL || !X509_STORE_set_default_paths(store)) { @@ -135,7 +139,7 @@ int main(int argc, char *argv[]) for (i = 1; i < threadcount; i++) ttime = ossl_time_add(ttime, times[i]); - avcalltime = ((double)ossl_time2ticks(ttime) / (double)NUM_CALLS_PER_TEST) /(double)OSSL_TIME_US; + avcalltime = ((double)ossl_time2ticks(ttime) / num_calls) /(double)OSSL_TIME_US; if (terse) printf("%lf\n", avcalltime);