diff --git a/src/bench/chacha20.cpp b/src/bench/chacha20.cpp index 371651771f79..e214d53235da 100644 --- a/src/bench/chacha20.cpp +++ b/src/bench/chacha20.cpp @@ -8,8 +8,10 @@ #include #include +#include #include #include +#include #include /* Number of bytes to process per iteration */ @@ -20,24 +22,32 @@ static const uint64_t BUFFER_SIZE_LARGE = 1024*1024; static void CHACHA20(benchmark::Bench& bench, size_t buffersize) { std::vector key(32, {}); - ChaCha20 ctx(key); - ctx.Seek({0, 0}, 0); + std::optional ctx; std::vector in(buffersize, {}); std::vector out(buffersize, {}); - bench.batch(in.size()).unit("byte").run([&] { - ctx.Crypt(in, out); + bench.batch(in.size()).unit("byte").epochIterations(1) + .setup([&] { + ctx.emplace(key); + ctx->Seek({0, 0}, 0); + }).run([&] { + ctx->Crypt(in, out); + assert(out[0] == std::byte{0x76}); }); } static void FSCHACHA20POLY1305(benchmark::Bench& bench, size_t buffersize) { std::vector key(32); - FSChaCha20Poly1305 ctx(key, 224); + std::optional ctx; std::vector in(buffersize); std::vector aad; std::vector out(buffersize + FSChaCha20Poly1305::EXPANSION); - bench.batch(in.size()).unit("byte").run([&] { - ctx.Encrypt(in, aad, out); + bench.batch(in.size()).unit("byte").epochIterations(1) + .setup([&] { + ctx.emplace(key, 224); + }).run([&] { + ctx->Encrypt(in, aad, out); + assert(out[0] == std::byte{0x9f}); }); } diff --git a/src/bench/lockedpool.cpp b/src/bench/lockedpool.cpp index 27fd609a52dc..67eebc9cc8af 100644 --- a/src/bench/lockedpool.cpp +++ b/src/bench/lockedpool.cpp @@ -5,37 +5,43 @@ #include #include +#include #include #include +#include #include #define ASIZE 2048 #define MSIZE 2048 +static constexpr uint32_t INITIAL_STATE{0x12345678}; static void BenchLockedPool(benchmark::Bench& bench) { void *synth_base = reinterpret_cast(0x08000000); const size_t synth_size = 1024*1024; - Arena b(synth_base, synth_size, 16); + std::optional b; std::vector addr{ASIZE, nullptr}; - uint32_t s = 0x12345678; - bench.run([&] { + uint32_t s = INITIAL_STATE; + bench.epochIterations(1) + .setup([&] { + b.emplace(synth_base, synth_size, 16); + addr.assign(ASIZE, nullptr); + s = INITIAL_STATE; + }).run([&] { + assert(s == INITIAL_STATE); int idx = s & (addr.size() - 1); if (s & 0x80000000) { - b.free(addr[idx]); + b->free(addr[idx]); addr[idx] = nullptr; } else if (!addr[idx]) { - addr[idx] = b.alloc((s >> 16) & (MSIZE - 1)); + addr[idx] = b->alloc((s >> 16) & (MSIZE - 1)); } bool lsb = s & 1; s >>= 1; if (lsb) s ^= 0xf00f00f0; // LFSR period 0xf7ffffe0 }); - for (void *ptr: addr) - b.free(ptr); - addr.clear(); } BENCHMARK(BenchLockedPool); diff --git a/src/bench/mempool_ephemeral_spends.cpp b/src/bench/mempool_ephemeral_spends.cpp index f0d8eb0bea7b..afaa5a1f23d1 100644 --- a/src/bench/mempool_ephemeral_spends.cpp +++ b/src/bench/mempool_ephemeral_spends.cpp @@ -59,8 +59,8 @@ static void MempoolCheckEphemeralSpends(benchmark::Bench& bench) CMutableTransaction tx2; tx2.vin.resize(tx1.vout.size()); for (size_t i = 0; i < tx2.vin.size(); i++) { - tx2.vin[0].prevout.hash = parent_txid; - tx2.vin[0].prevout.n = i; + tx2.vin[i].prevout.hash = parent_txid; + tx2.vin[i].prevout.n = i; } tx2.vout.resize(1); @@ -71,6 +71,8 @@ static void MempoolCheckEphemeralSpends(benchmark::Bench& bench) const CTransactionRef tx2_r{MakeTransactionRef(tx2)}; AddTx(tx1_r, pool); + assert(tx2_r->vin.back().prevout.hash == parent_txid); + assert(tx2_r->vin.back().prevout.n == tx2_r->vin.size() - 1); uint32_t iteration{0}; diff --git a/src/bench/nanobench.h b/src/bench/nanobench.h index 1f798b848b3d..12a03bc42d71 100644 --- a/src/bench/nanobench.h +++ b/src/bench/nanobench.h @@ -40,6 +40,7 @@ /////////////////////////////////////////////////////////////////////////////////////////////////// #include // high_resolution_clock +#include // assert #include // memcpy #include // for std::ostream* custom output target in Config #include // all names @@ -1238,6 +1239,8 @@ class SetupRunner { template ANKERL_NANOBENCH_NO_SANITIZE("integer") Bench& run(Op&& op) { + assert(mBench.epochIterations() == 1 && + "setup() runs once per epoch, not once per iteration; use epochIterations(1) when setup() must reset state for each timed call"); return mBench.runImpl(mSetupOp, std::forward(op)); } diff --git a/src/bench/pool.cpp b/src/bench/pool.cpp index cf4ba132bf43..370c35c5c507 100644 --- a/src/bench/pool.cpp +++ b/src/bench/pool.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -15,11 +16,15 @@ template void BenchFillClearMap(benchmark::Bench& bench, Map& map) { size_t batch_size = 5000; + size_t empty_bucket_count = 0; - // make sure each iteration of the benchmark contains exactly 5000 inserts and one clear. - // do this at least 10 times so we get reasonable accurate results - - bench.batch(batch_size).minEpochIterations(10).run([&] { + bench.batch(batch_size).epochIterations(1) + .setup([&] { + map.clear(); + map.rehash(0); + empty_bucket_count = map.bucket_count(); + }).run([&] { + assert(map.bucket_count() == empty_bucket_count); auto rng = ankerl::nanobench::Rng(1234); for (size_t i = 0; i < batch_size; ++i) { map[rng()]; diff --git a/src/bench/readwriteblock.cpp b/src/bench/readwriteblock.cpp index b8e226c6eb96..0285559cb916 100644 --- a/src/bench/readwriteblock.cpp +++ b/src/bench/readwriteblock.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include static CBlock CreateTestBlock() @@ -28,12 +29,18 @@ static CBlock CreateTestBlock() static void WriteBlockBench(benchmark::Bench& bench) { - const auto testing_setup{MakeNoLogFileContext(ChainType::MAIN)}; - auto& blockman{testing_setup->m_node.chainman->m_blockman}; const CBlock block{CreateTestBlock()}; - bench.run([&] { + std::unique_ptr testing_setup; + std::optional expected_pos; + bench.epochIterations(1) + .setup([&] { + testing_setup = MakeNoLogFileContext(ChainType::MAIN); + }).run([&] { + auto& blockman{testing_setup->m_node.chainman->m_blockman}; const auto pos{blockman.WriteBlock(block, 413'567)}; assert(!pos.IsNull()); + assert(!expected_pos || pos == *expected_pos); + expected_pos = pos; }); } diff --git a/src/bench/rollingbloom.cpp b/src/bench/rollingbloom.cpp index 8331eb6a7c90..913127f463b9 100644 --- a/src/bench/rollingbloom.cpp +++ b/src/bench/rollingbloom.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -15,8 +16,16 @@ static void RollingBloom(benchmark::Bench& bench) { CRollingBloomFilter filter(120000, 0.000001); std::vector data(32); + std::vector first_insert(32); + WriteLE32(first_insert.data(), 1); uint32_t count = 0; - bench.run([&] { + bench.epochIterations(1) + .setup([&] { + filter.reset(); + data.assign(32, 0); + count = 0; + }).run([&] { + assert(!filter.contains(first_insert)); count++; WriteLE32(data.data(), count); filter.insert(data); diff --git a/src/bench/wallet_balance.cpp b/src/bench/wallet_balance.cpp index 45f23494280a..d9cd4bbb9521 100644 --- a/src/bench/wallet_balance.cpp +++ b/src/bench/wallet_balance.cpp @@ -62,11 +62,9 @@ static void WalletBalance(benchmark::Bench& bench, const bool set_dirty, const b static void WalletBalanceDirty(benchmark::Bench& bench) { WalletBalance(bench, /*set_dirty=*/true, /*add_mine=*/true); } static void WalletBalanceClean(benchmark::Bench& bench) { WalletBalance(bench, /*set_dirty=*/false, /*add_mine=*/true); } -static void WalletBalanceMine(benchmark::Bench& bench) { WalletBalance(bench, /*set_dirty=*/false, /*add_mine=*/true); } static void WalletBalanceWatch(benchmark::Bench& bench) { WalletBalance(bench, /*set_dirty=*/false, /*add_mine=*/false); } BENCHMARK(WalletBalanceDirty); BENCHMARK(WalletBalanceClean); -BENCHMARK(WalletBalanceMine); BENCHMARK(WalletBalanceWatch); } // namespace wallet