From 0a5a45ff8ae437ddf1c3b8de425f30a44e6f5580 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sun, 26 Aug 2018 23:16:00 +0200 Subject: Add benchmarks --- test/bench_bitvec.cpp | 339 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 339 insertions(+) create mode 100644 test/bench_bitvec.cpp (limited to 'test/bench_bitvec.cpp') diff --git a/test/bench_bitvec.cpp b/test/bench_bitvec.cpp new file mode 100644 index 0000000..741b2d2 --- /dev/null +++ b/test/bench_bitvec.cpp @@ -0,0 +1,339 @@ +/* + Copyright (C) 2018 David Robillard + + This program is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free Software + Foundation, either version 2 of the License, or (at your option) any later + version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + details. + + You should have received a copy of the GNU General Public License along with + this program. If not, see . +*/ + +#include "bench_utils.hpp" + +#include "chilbert/BoundedBitVec.hpp" +#include "chilbert/DynamicBitVec.hpp" +#include "chilbert/SmallBitVec.hpp" +#include "chilbert/StaticBitVec.hpp" + +#include + +template +struct BenchAnd +{ + Duration operator()(Context& ctx) + { + const T v = make_random_bitvec(ctx); + T r = make_random_bitvec(ctx); + + return run_bench([&](auto) { r &= v; }); + } +}; + +template +struct BenchOr +{ + Duration operator()(Context& ctx) + { + const T v = make_random_bitvec(ctx); + T r = make_random_bitvec(ctx); + + return run_bench([&](auto) { r |= v; }); + } +}; + +template +struct BenchXor +{ + Duration operator()(Context& ctx) + { + const T v = make_random_bitvec(ctx); + T r = make_random_bitvec(ctx); + + return run_bench([&](auto) { r ^= v; }); + } +}; + +template +struct BenchSetOne +{ + Duration operator()(Context& ctx) + { + T v = make_random_bitvec(ctx); + return run_bench([&](const auto i) { v.set(i % N); }); + } +}; + +template +struct BenchSetAll +{ + Duration operator()(Context& ctx) + { + T v = make_random_bitvec(ctx); + return run_bench([&](auto) { v.set(); }); + } +}; + +template +struct BenchResetOne +{ + Duration operator()(Context& ctx) + { + T v = make_random_bitvec(ctx); + return run_bench([&](const auto i) { v.reset(i % N); }); + } +}; + +template +struct BenchResetAll +{ + Duration operator()(Context& ctx) + { + T v = make_random_bitvec(ctx); + return run_bench([&](auto) { v.reset(); }); + } +}; + +template +struct BenchFlipOne +{ + Duration operator()(Context& ctx) + { + T v = make_random_bitvec(ctx); + return run_bench([&](const auto i) { v.flip(i % N); }); + } +}; + +template +struct BenchFlipAll +{ + Duration operator()(Context& ctx) + { + T v = make_random_bitvec(ctx); + return run_bench([&](auto) { v.flip(); }); + } +}; + +template +struct BenchNone +{ + Duration operator()(Context& ctx) + { + T v = make_random_bitvec(ctx); + bool r = false; + return run_bench([&](auto) { r = v.none(); }); + } +}; + +template +struct BenchCount +{ + Duration operator()(Context& ctx) + { + T v = make_random_bitvec(ctx); + volatile size_t r = 0; + return run_bench([&](auto) { r = v.count(); }); + } +}; + +template +struct BenchLeftShift +{ + Duration operator()(Context& ctx) + { + const T v = make_random_bitvec(ctx); + T r = v; + return run_bench([&](const auto i) { r <<= (i % N); }); + } +}; + +template +struct BenchRightShift +{ + Duration operator()(Context& ctx) + { + const T v = make_random_bitvec(ctx); + T r = v; + return run_bench([&](const auto i) { r >>= (i % N); }); + } +}; + +template +struct BenchLeftRotate +{ + Duration operator()(Context& ctx) + { + T v = make_random_bitvec(ctx); + return run_bench([&](const auto i) { v.rotl(i % N); }); + } +}; + +template +struct BenchRightRotate +{ + Duration operator()(Context& ctx) + { + T v = make_random_bitvec(ctx); + volatile bool r = false; + return run_bench([&](const auto i) { + v.rotr(i % N); + r = v.test(0); + }); + } +}; + +template +struct BenchFindFirst +{ + Duration operator()(Context& ctx) + { + T v = make_random_bitvec(ctx); + volatile size_t r = 0; + return run_bench([&](auto) { r = v.find_first(); }); + } +}; + +template +struct BenchGrayCode +{ + Duration operator()(Context& ctx) + { + const T v = make_random_bitvec(ctx); + T r = v; + + return run_bench([&](auto) { chilbert::detail::gray_code(r); }); + } +}; + +template +struct BenchGrayCodeInv +{ + Duration operator()(Context& ctx) + { + const T v = make_random_bitvec(ctx); + T r = v; + + return run_bench([&](auto) { chilbert::detail::gray_code_inv(r); }); + } +}; + +template +struct BenchComparison +{ + Duration operator()(Context& ctx) + { + std::vector vecs; + for (size_t i = 0; i < 32; ++i) { + vecs.emplace_back(make_random_bitvec(ctx)); + } + + volatile bool r = false; + + return run_bench([&](const auto i) { + r |= vecs[i % vecs.size()] < vecs[(i + 1) % vecs.size()]; + }); + } +}; + +template +struct BenchIteration +{ + Duration operator()(Context& ctx) + { + T v = make_random_bitvec(ctx); + auto i = v.begin(); + volatile bool r = false; + return run_bench([&](const auto) { + r = (++i == v.end()); + if (r) { + i = v.begin(); + } + }); + } +}; + +/// Run benchmark for size N +template