From: Loup Vaillant Date: Sun, 17 Feb 2019 18:25:52 +0000 (+0100) Subject: Removed division by zero in speed benchmarks X-Git-Url: https://git.codecow.com/?a=commitdiff_plain;h=2056365901882345172079ceaec353562804b801;p=Monocypher.git Removed division by zero in speed benchmarks If some library is so fast that it goes below the resolution of the timer we're using to measure it, the measured duration may be zero, and then trigger a division by zero when we convert it to a speed in Hz. This could possibly happen with a very fast library (Libsodium), on a very fast machine, with a sufficiently low resolution timer. This patch reworks and simplifies things a bit, and adds an explicit check. We now print "too fast to be measured" instead of dividing by zero. --- diff --git a/tests/speed-sodium.c b/tests/speed-sodium.c index a1c50ab..5ad35bd 100644 --- a/tests/speed-sodium.c +++ b/tests/speed-sodium.c @@ -126,12 +126,12 @@ static u64 edDSA_check(void) int main() { SODIUM_INIT; - print("Chacha20 ",chacha20() /DIV,"megabytes per second"); - print("Poly1305 ",poly1305() /DIV,"megabytes per second"); - print("Auth'd encryption",authenticated()/DIV,"megabytes per second"); - print("Blake2b ",blake2b() /DIV,"megabytes per second"); - print("Sha512 ",sha512() /DIV,"megabytes per second"); - print("Argon2i, 3 passes",argon2i() /DIV,"megabytes per second"); + print("Chacha20 ",chacha20() *MUL,"megabytes per second"); + print("Poly1305 ",poly1305() *MUL,"megabytes per second"); + print("Auth'd encryption",authenticated()*MUL,"megabytes per second"); + print("Blake2b ",blake2b() *MUL,"megabytes per second"); + print("Sha512 ",sha512() *MUL,"megabytes per second"); + print("Argon2i, 3 passes",argon2i() *MUL,"megabytes per second"); print("x25519 ",x25519() ,"exchanges per second"); print("EdDSA(sign) ",edDSA_sign() ,"signatures per second"); print("EdDSA(check) ",edDSA_check() ,"checks per second"); diff --git a/tests/speed-tweetnacl.c b/tests/speed-tweetnacl.c index 5607ad1..00a1f9e 100644 --- a/tests/speed-tweetnacl.c +++ b/tests/speed-tweetnacl.c @@ -102,10 +102,10 @@ static u64 edDSA_check(void) int main() { - print("Salsa20 ",salsa20() /DIV,"megabytes per second"); - print("Poly1305 ",poly1305() /DIV,"megabytes per second"); - print("Auth'd encryption",authenticated()/DIV,"megabytes per second"); - print("Sha512 ",sha512() /DIV,"megabytes per second"); + print("Salsa20 ",salsa20() *MUL,"megabytes per second"); + print("Poly1305 ",poly1305() *MUL,"megabytes per second"); + print("Auth'd encryption",authenticated()*MUL,"megabytes per second"); + print("Sha512 ",sha512() *MUL,"megabytes per second"); print("x25519 ",x25519() ,"exchanges per second"); print("EdDSA(sign) ",edDSA_sign() ,"signatures per second"); print("EdDSA(check) ",edDSA_check() ,"checks per second"); diff --git a/tests/speed.c b/tests/speed.c index 7cb1056..fbdf7d0 100644 --- a/tests/speed.c +++ b/tests/speed.c @@ -128,12 +128,12 @@ static u64 edDSA_check(void) int main() { - print("Chacha20 ",chacha20() /DIV,"megabytes per second"); - print("Poly1305 ",poly1305() /DIV,"megabytes per second"); - print("Auth'd encryption",authenticated()/DIV,"megabytes per second"); - print("Blake2b ",blake2b() /DIV,"megabytes per second"); - print("Sha512 ",sha512() /DIV,"megabytes per second"); - print("Argon2i, 3 passes",argon2i() /DIV,"megabytes per second"); + print("Chacha20 ",chacha20() *MUL,"megabytes per second"); + print("Poly1305 ",poly1305() *MUL,"megabytes per second"); + print("Auth'd encryption",authenticated()*MUL,"megabytes per second"); + print("Blake2b ",blake2b() *MUL,"megabytes per second"); + print("Sha512 ",sha512() *MUL,"megabytes per second"); + print("Argon2i, 3 passes",argon2i() *MUL,"megabytes per second"); print("x25519 ",x25519() ,"exchanges per second"); print("EdDSA(sign) ",edDSA_sign() ,"signatures per second"); print("EdDSA(check) ",edDSA_check() ,"checks per second"); diff --git a/tests/speed.h b/tests/speed.h index 5f47221..c83b001 100644 --- a/tests/speed.h +++ b/tests/speed.h @@ -10,38 +10,30 @@ typedef struct timespec timespec; #define KILOBYTE 1024 #define MEGABYTE 1024 * KILOBYTE #define SIZE (256 * KILOBYTE) -#define DIV (MEGABYTE / SIZE) +#define MUL (MEGABYTE / SIZE) +#define BILLION 1000000000 -static timespec diff(timespec start, timespec end) +// Difference in nanoseconds +static u64 diff(timespec start, timespec end) { - timespec duration; - duration.tv_sec = end.tv_sec - start.tv_sec; - duration.tv_nsec = end.tv_nsec - start.tv_nsec; - if (duration.tv_nsec < 0) { - duration.tv_nsec += 1000000000; - duration.tv_sec -= 1; - } - return duration; -} - -static timespec min(timespec a, timespec b) -{ - if (a.tv_sec < b.tv_sec || - (a.tv_sec == b.tv_sec && a.tv_nsec < b.tv_nsec)) { - return a; - } - return b; + return + (end.tv_sec - start.tv_sec ) * BILLION + + (end.tv_nsec - start.tv_nsec); } -static u64 speed(timespec duration) +static u64 min(u64 a, u64 b) { - static const u64 giga = 1000000000; - return giga / (duration.tv_nsec + duration.tv_sec * giga); + return a < b ? a : b; } -static void print(const char *name, u64 speed, const char *unit) +static void print(const char *name, u64 duration, const char *unit) { - printf("%s: %5" PRIu64 " %s\n", name, speed, unit); + if (duration == 0) { + printf("%s: too fast to be measured\n", name); + } else { + u64 speed_hz = BILLION / duration; + printf("%s: %5" PRIu64 " %s\n", name, speed_hz, unit); + } } #define TIMESTAMP(t) \ @@ -49,11 +41,7 @@ static void print(const char *name, u64 speed, const char *unit) clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &t) #define TIMING_START \ - timespec duration; \ - duration.tv_sec = -1; \ - duration.tv_nsec = -1; \ - duration.tv_sec = 3600 * 24; \ - duration.tv_nsec = 0; \ + u64 duration = -1u; \ FOR (i, 0, 500) { \ TIMESTAMP(start); @@ -61,4 +49,4 @@ static void print(const char *name, u64 speed, const char *unit) TIMESTAMP(end); \ duration = min(duration, diff(start, end)); \ } /* end FOR*/ \ - return speed(duration) + return duration