]> git.codecow.com Git - Monocypher.git/commitdiff
Removed division by zero in speed benchmarks
authorLoup Vaillant <loup@loup-vaillant.fr>
Sun, 17 Feb 2019 18:25:52 +0000 (19:25 +0100)
committerLoup Vaillant <loup@loup-vaillant.fr>
Sun, 17 Feb 2019 18:25:52 +0000 (19:25 +0100)
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.

tests/speed-sodium.c
tests/speed-tweetnacl.c
tests/speed.c
tests/speed.h

index a1c50abeeb977936162c7f783908242b41cbdfc2..5ad35bdba1722520429b7225c3acf377aa66d307 100644 (file)
@@ -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");
index 5607ad11fe29a6c7462ca934cb0e541995a1684d..00a1f9e5f7bbcb6dc6e6b8430d86de2e8a496c7c 100644 (file)
@@ -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");
index 7cb10563bb6ed68efbd70eedebaa5e16c9b167c1..fbdf7d0d1f56e50e161c71559c6630a0eb2377c5 100644 (file)
@@ -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");
index 5f472211fa989f834dcc69a0bccd5bd30aa7f157..c83b001594328dafc7085020e733cd520d0a077c 100644 (file)
@@ -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