mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-09-14 23:37:51 +02:00
Merge bitcoin/bitcoin#35124: bench: fix benchmark fixtures and setup checks
e6430b2773bench: make `setup()` use single-iteration epochs (Lőrinc)ba0078e3bfbench: fix ephemeral spend inputs (Lőrinc)b8b7f896e8bench: drop duplicate balance benchmark (Lőrinc) Pull request description: ### Context Found while reviewing https://github.com/bitcoin/bitcoin/pull/35018, which led to a few additional benchmark fixes. ### Problem `MempoolCheckEphemeralSpends` populated every child input by writing to `vin[0]`. That left only one child input pointing at the parent transaction, while the remaining inputs kept default prevouts. `WalletBalanceMine` duplicated `WalletBalanceClean` exactly. The same review also showed that nanobench `setup()` can be misused as though it runs once per timed call. It actually runs once per epoch, so using it with multiple epoch iterations can silently leave later iterations with different preconditions. ### Fix Write each ephemeral-spend prevout to the matching child input and assert that the last input spends the last parent output. Remove the duplicate wallet balance benchmark registration. Add a nanobench assertion that `setup()` is only used with `epochIterations(1)`. > [!NOTE] > This PR included a few benchmark adjustments originally which made the tests unstable and were reverted. ACKs for top commit: davidgumberg: crACKe6430b2773sedited: ACKe6430b2773Tree-SHA512: 667c67975d7a3e21333f6c8a4e037ad700bc6dcbd7039e002534e4f2a9328195a618b78accf097e7c43402a1f1b25e32b0c39642fd465729ab4c337abe4f23f1
This commit is contained in:
@@ -162,8 +162,7 @@ static void AddrManAddThenGood(benchmark::Bench& bench)
|
||||
CreateAddresses();
|
||||
|
||||
std::optional<AddrMan> addrman;
|
||||
bench.epochIterations(1)
|
||||
.setup([&] {
|
||||
bench.setup([&] {
|
||||
addrman.emplace(EMPTY_NETGROUPMAN, /*deterministic=*/false, ADDRMAN_CONSISTENCY_CHECK_RATIO);
|
||||
AddAddressesToAddrMan(*addrman);
|
||||
})
|
||||
|
||||
@@ -33,7 +33,7 @@ static void CheckBlockTest(benchmark::Bench& bench)
|
||||
const auto block_data{benchmark::data::block413567};
|
||||
|
||||
CBlock block;
|
||||
bench.unit("block").epochIterations(1)
|
||||
bench.unit("block")
|
||||
.setup([&] {
|
||||
block = CBlock{};
|
||||
SpanReader{block_data} >> TX_WITH_WITNESS(block);
|
||||
|
||||
@@ -115,8 +115,7 @@ static void BnBExhaustion(benchmark::Bench& bench)
|
||||
{
|
||||
std::vector<OutputGroup> utxo_pool;
|
||||
CAmount target;
|
||||
bench.epochIterations(1)
|
||||
.setup([&] { target = make_hard_case(17, utxo_pool); })
|
||||
bench.setup([&] { target = make_hard_case(17, utxo_pool); })
|
||||
.run([&] {
|
||||
auto res{SelectCoinsBnB(utxo_pool, target, /*cost_of_change=*/0, MAX_STANDARD_TX_WEIGHT)}; // Should exhaust
|
||||
ankerl::nanobench::doNotOptimizeAway(res);
|
||||
|
||||
@@ -62,8 +62,7 @@ static void LoadExternalBlockFile(benchmark::Bench& bench)
|
||||
|
||||
std::multimap<uint256, FlatFilePos> blocks_with_unknown_parent;
|
||||
FlatFilePos pos;
|
||||
bench.epochIterations(1)
|
||||
.setup([&] {
|
||||
bench.setup([&] {
|
||||
blocks_with_unknown_parent.clear();
|
||||
pos = FlatFilePos{};
|
||||
})
|
||||
|
||||
@@ -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,7 @@ static void MempoolCheckEphemeralSpends(benchmark::Bench& bench)
|
||||
const CTransactionRef tx2_r{MakeTransactionRef(tx2)};
|
||||
|
||||
AddTx(tx1_r, pool);
|
||||
assert(tx2_r->vin.back().prevout == COutPoint(parent_txid, tx1_r->vout.size() - 1));
|
||||
|
||||
uint32_t iteration{0};
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <chrono> // high_resolution_clock
|
||||
#include <cassert> // assert
|
||||
#include <cstring> // memcpy
|
||||
#include <iosfwd> // for std::ostream* custom output target in Config
|
||||
#include <string> // all names
|
||||
@@ -1013,7 +1014,7 @@ public:
|
||||
ANKERL_NANOBENCH(NODISCARD) Config const& config() const noexcept;
|
||||
|
||||
/**
|
||||
* @brief Configure an untimed setup step per epoch (fluent API).
|
||||
* @brief Configure an untimed setup step per epoch (forces single-iteration epochs).
|
||||
*
|
||||
* Example: `bench.setup(...).run(...);`
|
||||
*/
|
||||
@@ -1238,6 +1239,9 @@ public:
|
||||
template <typename Op>
|
||||
ANKERL_NANOBENCH_NO_SANITIZE("integer")
|
||||
Bench& run(Op&& op) {
|
||||
assert((mBench.epochIterations() <= 1) &&
|
||||
"setup() runs once per epoch, not once per iteration; it requires epochIterations(1)");
|
||||
mBench.epochIterations(1);
|
||||
return mBench.runImpl(mSetupOp, std::forward<Op>(op));
|
||||
}
|
||||
|
||||
|
||||
@@ -22,8 +22,7 @@ static void FindByte(benchmark::Bench& bench)
|
||||
file.seek(0, SEEK_SET);
|
||||
BufferedFile bf{file, /*nBufSize=*/file_size + 1, /*nRewindIn=*/file_size};
|
||||
|
||||
bench.epochIterations(1)
|
||||
.setup([&] { bf.SetPos(0); })
|
||||
bench.setup([&] { bf.SetPos(0); })
|
||||
.run([&] { bf.FindByte(std::byte(1)); });
|
||||
|
||||
assert(file.fclose() == 0);
|
||||
|
||||
@@ -115,7 +115,7 @@ static void VerifyNestedIfScript(benchmark::Bench& bench)
|
||||
for (int i = 0; i < 100; ++i) {
|
||||
script << OP_ENDIF;
|
||||
}
|
||||
bench.unit("script").epochIterations(1)
|
||||
bench.unit("script")
|
||||
.setup([&] { stack.clear(); })
|
||||
.run([&] {
|
||||
ScriptError error;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user