Skip to content

Commit 6f51f6f

Browse files
author
MarcoFalke
committed
Merge #18754: bench: add CAddrMan benchmarks
a9b9577 bench: add CAddrMan benchmarks (Vasil Dimov) Pull request description: The added benchmarks exercise the public methods Add(), GetAddr(), Select() and Good(). ACKs for top commit: naumenkogs: utACK a9b9577 MarcoFalke: ACK a9b9577 Tree-SHA512: af54b2fbd97db34faf4cc6c9bacb20d2c97d0aaddb9cf91b220bc2e09227b55345402ed17e34450745493e3a2b286c176c031cdeb477415570a757cee16b06a8
2 parents 9fac600 + a9b9577 commit 6f51f6f

File tree

2 files changed

+141
-0
lines changed

2 files changed

+141
-0
lines changed

src/Makefile.bench.include

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ GENERATED_BENCH_FILES = $(RAW_BENCH_FILES:.raw=.raw.h)
1212

1313
bench_bench_bitcoin_SOURCES = \
1414
$(RAW_BENCH_FILES) \
15+
bench/addrman.cpp \
1516
bench/bench_bitcoin.cpp \
1617
bench/bench.cpp \
1718
bench/bench.h \

src/bench/addrman.cpp

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
// Copyright (c) 2020-2020 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#include <addrman.h>
6+
#include <bench/bench.h>
7+
#include <random.h>
8+
#include <util/time.h>
9+
10+
#include <vector>
11+
12+
/* A "source" is a source address from which we have received a bunch of other addresses. */
13+
14+
static constexpr size_t NUM_SOURCES = 64;
15+
static constexpr size_t NUM_ADDRESSES_PER_SOURCE = 256;
16+
17+
static std::vector<CAddress> g_sources;
18+
static std::vector<std::vector<CAddress>> g_addresses;
19+
20+
static void CreateAddresses()
21+
{
22+
if (g_sources.size() > 0) { // already created
23+
return;
24+
}
25+
26+
FastRandomContext rng(uint256(std::vector<unsigned char>(32, 123)));
27+
28+
auto randAddr = [&rng]() {
29+
in6_addr addr;
30+
memcpy(&addr, rng.randbytes(sizeof(addr)).data(), sizeof(addr));
31+
32+
uint16_t port;
33+
memcpy(&port, rng.randbytes(sizeof(port)).data(), sizeof(port));
34+
if (port == 0) {
35+
port = 1;
36+
}
37+
38+
CAddress ret(CService(addr, port), NODE_NETWORK);
39+
40+
ret.nTime = GetAdjustedTime();
41+
42+
return ret;
43+
};
44+
45+
for (size_t source_i = 0; source_i < NUM_SOURCES; ++source_i) {
46+
g_sources.emplace_back(randAddr());
47+
g_addresses.emplace_back();
48+
for (size_t addr_i = 0; addr_i < NUM_ADDRESSES_PER_SOURCE; ++addr_i) {
49+
g_addresses[source_i].emplace_back(randAddr());
50+
}
51+
}
52+
}
53+
54+
static void AddAddressesToAddrMan(CAddrMan& addrman)
55+
{
56+
for (size_t source_i = 0; source_i < NUM_SOURCES; ++source_i) {
57+
addrman.Add(g_addresses[source_i], g_sources[source_i]);
58+
}
59+
}
60+
61+
static void FillAddrMan(CAddrMan& addrman)
62+
{
63+
CreateAddresses();
64+
65+
AddAddressesToAddrMan(addrman);
66+
}
67+
68+
/* Benchmarks */
69+
70+
static void AddrManAdd(benchmark::State& state)
71+
{
72+
CreateAddresses();
73+
74+
CAddrMan addrman;
75+
76+
while (state.KeepRunning()) {
77+
AddAddressesToAddrMan(addrman);
78+
addrman.Clear();
79+
}
80+
}
81+
82+
static void AddrManSelect(benchmark::State& state)
83+
{
84+
CAddrMan addrman;
85+
86+
FillAddrMan(addrman);
87+
88+
while (state.KeepRunning()) {
89+
const auto& address = addrman.Select();
90+
assert(address.GetPort() > 0);
91+
}
92+
}
93+
94+
static void AddrManGetAddr(benchmark::State& state)
95+
{
96+
CAddrMan addrman;
97+
98+
FillAddrMan(addrman);
99+
100+
while (state.KeepRunning()) {
101+
const auto& addresses = addrman.GetAddr();
102+
assert(addresses.size() > 0);
103+
}
104+
}
105+
106+
static void AddrManGood(benchmark::State& state)
107+
{
108+
/* Create many CAddrMan objects - one to be modified at each loop iteration.
109+
* This is necessary because the CAddrMan::Good() method modifies the
110+
* object, affecting the timing of subsequent calls to the same method and
111+
* we want to do the same amount of work in every loop iteration. */
112+
113+
const uint64_t numLoops = state.m_num_iters * state.m_num_evals;
114+
115+
std::vector<CAddrMan> addrmans(numLoops);
116+
for (auto& addrman : addrmans) {
117+
FillAddrMan(addrman);
118+
}
119+
120+
auto markSomeAsGood = [](CAddrMan& addrman) {
121+
for (size_t source_i = 0; source_i < NUM_SOURCES; ++source_i) {
122+
for (size_t addr_i = 0; addr_i < NUM_ADDRESSES_PER_SOURCE; ++addr_i) {
123+
if (addr_i % 32 == 0) {
124+
addrman.Good(g_addresses[source_i][addr_i]);
125+
}
126+
}
127+
}
128+
};
129+
130+
uint64_t i = 0;
131+
while (state.KeepRunning()) {
132+
markSomeAsGood(addrmans.at(i));
133+
++i;
134+
}
135+
}
136+
137+
BENCHMARK(AddrManAdd, 5);
138+
BENCHMARK(AddrManSelect, 1000000);
139+
BENCHMARK(AddrManGetAddr, 500);
140+
BENCHMARK(AddrManGood, 2);

0 commit comments

Comments
 (0)