mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-01-21 15:50:07 +01:00
bench: make MerkleRoot benchmark more representative
Two versions are run now, one with the mutation calculations, the other without.
To avoid unwanted compiler optimizations, we assert the expected hash, which should inhibit aggressive optimization.
To make the benchmark more similar to production `ComputeMerkleRoot` call sites, the input leaves-copying is made explicit before each run.
> ./build/bin/bench_bitcoin -filter='MerkleRoot.*' -min-time=1000
| ns/leaf | leaf/s | err% | total | benchmark
|--------------------:|--------------------:|--------:|----------:|:----------
| 44.18 | 22,634,858.70 | 0.0% | 1.10 | `MerkleRoot`
| 44.66 | 22,390,601.03 | 0.0% | 1.10 | `MerkleRootWithMutation`
Massif memory measurements show the excessive memory reservations:
MB
1.332^ :
| # :
| # :
| # :
| # :
| # @ :
| # @ :
| # @ :
| # @ :
| # @ :
| # @ :
| # @ :
| # @ :
| #::::@::::::::::::::::::::::::::::::::::::::::::::::::::::::@:::::@::::
| #: ::@::::: :::::::: :: ::: :::::: : : :: ::: ::: : : : ::::@:::::@::::
| #: ::@::::: :::::::: :: ::: :::::: : : :: ::: ::: : : : ::::@:::::@::::
| #: ::@::::: :::::::: :: ::: :::::: : : :: ::: ::: : : : ::::@:::::@::::
| #: ::@::::: :::::::: :: ::: :::::: : : :: ::: ::: : : : ::::@:::::@::::
| #: ::@::::: :::::::: :: ::: :::::: : : :: ::: ::: : : : ::::@:::::@::::
| #: ::@::::: :::::::: :: ::: :::::: : : :: ::: ::: : : : ::::@:::::@::::
0 +----------------------------------------------------------------------->s
0 226.2
showing the reallocations clearly in the stacks:
97.87% (1,366,841B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
->41.25% (576,064B) 0x969717: allocate (new_allocator.h:151)
| ->41.25% (576,064B) 0x969717: allocate (allocator.h:203)
| ->41.25% (576,064B) 0x969717: allocate (alloc_traits.h:614)
| ->41.25% (576,064B) 0x969717: _M_allocate (stl_vector.h:387)
| ->41.25% (576,064B) 0x969717: _M_realloc_append<const uint256&> (vector.tcc:572)
| ->41.25% (576,064B) 0x969717: push_back (stl_vector.h:1427)
| ->41.25% (576,064B) 0x969717: ComputeMerkleRoot(std::vector<uint256, std::allocator<uint256> >, bool*) (merkle.cpp:55)
| ->41.25% (576,064B) 0x2235A7: operator() (merkle_root.cpp:31)
| ->41.25% (576,064B) 0x2235A7: ankerl::nanobench::Bench& ankerl::nanobench::Bench::run<MerkleRoot(ankerl::nanobench::Bench&)::{lambda()
Co-authored-by: Hodlinator <172445034+hodlinator@users.noreply.github.com>
This commit is contained in:
@@ -7,21 +7,33 @@
|
||||
#include <random.h>
|
||||
#include <uint256.h>
|
||||
|
||||
#include <cassert>
|
||||
#include <vector>
|
||||
|
||||
static void MerkleRoot(benchmark::Bench& bench)
|
||||
{
|
||||
FastRandomContext rng(true);
|
||||
std::vector<uint256> leaves;
|
||||
leaves.resize(9001);
|
||||
for (auto& item : leaves) {
|
||||
FastRandomContext rng{/*fDeterministic=*/true};
|
||||
|
||||
std::vector<uint256> hashes{};
|
||||
hashes.resize(9001);
|
||||
for (auto& item : hashes) {
|
||||
item = rng.rand256();
|
||||
}
|
||||
bench.batch(leaves.size()).unit("leaf").run([&] {
|
||||
bool mutation = false;
|
||||
uint256 hash = ComputeMerkleRoot(std::vector<uint256>(leaves), &mutation);
|
||||
leaves[mutation] = hash;
|
||||
});
|
||||
|
||||
constexpr uint256 expected_root{"d8d4dfd014a533bc3941b8663fa6e7f3a8707af124f713164d75b0c3179ecb08"};
|
||||
for (bool mutate : {false, true}) {
|
||||
bench.name(mutate ? "MerkleRootWithMutation" : "MerkleRoot").batch(hashes.size()).unit("leaf").run([&] {
|
||||
std::vector<uint256> leaves;
|
||||
leaves.resize(hashes.size());
|
||||
for (size_t s = 0; s < hashes.size(); s++) {
|
||||
leaves[s] = hashes[s];
|
||||
}
|
||||
|
||||
bool mutated{false};
|
||||
const uint256 root{ComputeMerkleRoot(std::move(leaves), mutate ? &mutated : nullptr)};
|
||||
assert(root == expected_root);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
BENCHMARK(MerkleRoot, benchmark::PriorityLevel::HIGH);
|
||||
|
||||
Reference in New Issue
Block a user