/ src / minisketch / src / bench.cpp
bench.cpp
  1  /**********************************************************************
  2   * Copyright (c) 2018 Pieter Wuille, Greg Maxwell, Gleb Naumenko      *
  3   * Distributed under the MIT software license, see the accompanying   *
  4   * file LICENSE or http://www.opensource.org/licenses/mit-license.php.*
  5   **********************************************************************/
  6  
  7  #include "../include/minisketch.h"
  8  #include <string.h>
  9  #include <memory>
 10  #include <vector>
 11  #include <chrono>
 12  #include <random>
 13  #include <set>
 14  #include <algorithm>
 15  
 16  int main(int argc, char** argv) {
 17      if (argc < 1 || argc > 4) {
 18          printf("Usage: %s [syndromes=150] [errors=syndromes] [iters=10]\n", argv[0]);
 19          return 1;
 20      }
 21      int syndromes = argc > 1 ? strtoul(argv[1], NULL, 10) : 150;
 22      int errors = argc > 2 ? strtoul(argv[2], NULL, 10) : syndromes;
 23      int iters = argc > 3 ? strtoul(argv[3], NULL, 10) : 10;
 24      if (syndromes < 0 || syndromes > 1000000) {
 25          printf("Number of syndromes (%i) out of range 0..1000000\n", syndromes);
 26          return 1;
 27      }
 28      if (errors < 0) {
 29          printf("Number of errors (%i) is negative(%i)\n", errors, syndromes);
 30          return 1;
 31      }
 32      if (iters < 0 || iters > 1000000000) {
 33          printf("Number of iterations (%i) out of range 0..1000000000\n", iters);
 34          return 1;
 35      }
 36      uint32_t max_impl = minisketch_implementation_max();
 37      for (int bits = 2; bits <= 64; ++bits) {
 38          if (errors > pow(2.0, bits - 1)) continue;
 39          if (!minisketch_bits_supported(bits)) continue;
 40          printf("recover[ms]\t% 3i\t", bits);
 41          for (uint32_t impl = 0; impl <= max_impl; ++impl) {
 42              std::vector<minisketch*> states;
 43              std::vector<uint64_t> roots(2 * syndromes);
 44              std::random_device rng;
 45              std::uniform_int_distribution<uint64_t> dist(1, (uint64_t(1) << bits) - 1);
 46              states.resize(iters);
 47              std::vector<double> benches;
 48              benches.reserve(iters);
 49              for (int i = 0; i < iters; ++i) {
 50                  states[i] = minisketch_create(bits, impl, syndromes);
 51                  if (!states[i]) break;
 52                  std::set<uint64_t> done;
 53                  for (int j = 0; j < errors; ++j) {
 54                      uint64_t r;
 55                      do {
 56                          r = dist(rng);
 57                      } while (done.count(r));
 58                      done.insert(r);
 59                      minisketch_add_uint64(states[i], r);
 60                  }
 61              }
 62              if (!states[0]) {
 63                  printf("         -\t");
 64              } else {
 65                  for (auto& state : states) {
 66                      auto start = std::chrono::steady_clock::now();
 67                      minisketch_decode(state, 2 * syndromes, roots.data());
 68                      auto stop = std::chrono::steady_clock::now();
 69                      std::chrono::duration<double> dur(stop - start);
 70                      benches.push_back(dur.count());
 71                  }
 72                  std::sort(benches.begin(), benches.end());
 73                  printf("% 10.5f\t", benches[0] * 1000.0);
 74              }
 75              for (auto& state : states) {
 76                  minisketch_destroy(state);
 77              }
 78          }
 79          printf("\n");
 80          printf("create[ns]\t% 3i\t", bits);
 81          for (uint32_t impl = 0; impl <= max_impl; ++impl) {
 82              std::vector<minisketch*> states;
 83              std::random_device rng;
 84              std::uniform_int_distribution<uint64_t> dist;
 85              std::vector<uint64_t> data;
 86              data.resize(errors * 10);
 87              states.resize(iters);
 88              std::vector<double> benches;
 89              benches.reserve(iters);
 90              for (int i = 0; i < iters; ++i) {
 91                  states[i] = minisketch_create(bits, impl, syndromes);
 92              }
 93              for (size_t i = 0; i < data.size(); ++i) {
 94                  data[i] = dist(rng);
 95              }
 96              if (!states[0]) {
 97                  printf("         -\t");
 98              } else {
 99                  for (auto& state : states) {
100                      auto start = std::chrono::steady_clock::now();
101                      for (auto val : data) {
102                          minisketch_add_uint64(state, val);
103                      }
104                      auto stop = std::chrono::steady_clock::now();
105                      std::chrono::duration<double> dur(stop - start);
106                      benches.push_back(dur.count());
107                  }
108                  std::sort(benches.begin(), benches.end());
109                  printf("% 10.5f\t", benches[0] * 1000000000.0 / data.size() / syndromes);
110              }
111              for (auto& state : states) {
112                  minisketch_destroy(state);
113              }
114          }
115          printf("\n");
116      }
117      return 0;
118  }