diff options
author | Pieter Wuille <pieter@wuille.net> | 2021-05-04 18:13:33 -0700 |
---|---|---|
committer | fanquake <fanquake@gmail.com> | 2021-10-21 09:39:16 +0800 |
commit | 54b5e1aeab73953c1f12ec2c041572038f6f59da (patch) | |
tree | 51eaed3c1a086b5d0cc866fb140652308b09199f /src/minisketchwrapper.cpp | |
parent | ee9dc71c1bc16205494f2a0aebe575a3c062ff52 (diff) |
Add thin Minisketch wrapper to pick best implementation
Diffstat (limited to 'src/minisketchwrapper.cpp')
-rw-r--r-- | src/minisketchwrapper.cpp | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/src/minisketchwrapper.cpp b/src/minisketchwrapper.cpp new file mode 100644 index 0000000000..fb176fb153 --- /dev/null +++ b/src/minisketchwrapper.cpp @@ -0,0 +1,77 @@ +// Copyright (c) 2021 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include <minisketchwrapper.h> + +#include <logging.h> +#include <util/time.h> + +#include <minisketch.h> + +#include <algorithm> +#include <cstddef> +#include <cstdint> +#include <optional> +#include <utility> +#include <vector> + +namespace { + +static constexpr uint32_t BITS = 32; + +uint32_t FindBestImplementation() +{ + std::optional<std::pair<int64_t, uint32_t>> best; + + uint32_t max_impl = Minisketch::MaxImplementation(); + for (uint32_t impl = 0; impl <= max_impl; ++impl) { + std::vector<int64_t> benches; + uint64_t offset = 0; + /* Run a little benchmark with capacity 32, adding 184 entries, and decoding 11 of them once. */ + for (int b = 0; b < 11; ++b) { + if (!Minisketch::ImplementationSupported(BITS, impl)) break; + Minisketch sketch(BITS, impl, 32); + auto start = GetTimeMicros(); + for (uint64_t e = 0; e < 100; ++e) { + sketch.Add(e*1337 + b*13337 + offset); + } + for (uint64_t e = 0; e < 84; ++e) { + sketch.Add(e*1337 + b*13337 + offset); + } + offset += (*sketch.Decode(32))[0]; + auto stop = GetTimeMicros(); + benches.push_back(stop - start); + } + /* Remember which implementation has the best median benchmark time. */ + if (!benches.empty()) { + std::sort(benches.begin(), benches.end()); + if (!best || best->first > benches[5]) { + best = std::make_pair(benches[5], impl); + } + } + } + assert(best.has_value()); + LogPrintf("Using Minisketch implementation number %i\n", best->second); + return best->second; +} + +uint32_t Minisketch32Implementation() +{ + // Fast compute-once idiom. + static uint32_t best = FindBestImplementation(); + return best; +} + +} // namespace + + +Minisketch MakeMinisketch32(size_t capacity) +{ + return Minisketch(BITS, Minisketch32Implementation(), capacity); +} + +Minisketch MakeMinisketch32FP(size_t max_elements, uint32_t fpbits) +{ + return Minisketch::CreateFP(BITS, Minisketch32Implementation(), max_elements, fpbits); +} |