Skip to content

Commit 054d664

Browse files
committed
Merge #9498: Basic CCheckQueue Benchmarks
aad4cb5 Address ryanofsky feedback on CCheckQueue benchmarks. Eliminated magic numbers, fixed scoping of vectors (and memory movement component of benchmark). (Jeremy Rubin) 9f03110 Add Basic CheckQueue Benchmark (Jeremy Rubin)
2 parents e9e7993 + aad4cb5 commit 054d664

File tree

2 files changed

+104
-0
lines changed

2 files changed

+104
-0
lines changed

src/Makefile.bench.include

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ bench_bench_bitcoin_SOURCES = \
1515
bench/bench.cpp \
1616
bench/bench.h \
1717
bench/checkblock.cpp \
18+
bench/checkqueue.cpp \
1819
bench/Examples.cpp \
1920
bench/rollingbloom.cpp \
2021
bench/crypto_hash.cpp \

src/bench/checkqueue.cpp

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
// Copyright (c) 2015 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 "bench.h"
6+
#include "util.h"
7+
#include "validation.h"
8+
#include "checkqueue.h"
9+
#include "prevector.h"
10+
#include <vector>
11+
#include <boost/thread/thread.hpp>
12+
#include "random.h"
13+
14+
15+
// This Benchmark tests the CheckQueue with the lightest
16+
// weight Checks, so it should make any lock contention
17+
// particularly visible
18+
static const int MIN_CORES = 2;
19+
static const size_t BATCHES = 101;
20+
static const size_t BATCH_SIZE = 30;
21+
static const int PREVECTOR_SIZE = 28;
22+
static const int QUEUE_BATCH_SIZE = 128;
23+
static void CCheckQueueSpeed(benchmark::State& state)
24+
{
25+
struct FakeJobNoWork {
26+
bool operator()()
27+
{
28+
return true;
29+
}
30+
void swap(FakeJobNoWork& x){};
31+
};
32+
CCheckQueue<FakeJobNoWork> queue {QUEUE_BATCH_SIZE};
33+
boost::thread_group tg;
34+
for (auto x = 0; x < std::max(MIN_CORES, GetNumCores()); ++x) {
35+
tg.create_thread([&]{queue.Thread();});
36+
}
37+
while (state.KeepRunning()) {
38+
CCheckQueueControl<FakeJobNoWork> control(&queue);
39+
40+
// We call Add a number of times to simulate the behavior of adding
41+
// a block of transactions at once.
42+
43+
std::vector<std::vector<FakeJobNoWork>> vBatches(BATCHES);
44+
for (auto& vChecks : vBatches) {
45+
vChecks.resize(BATCH_SIZE);
46+
}
47+
for (auto& vChecks : vBatches) {
48+
// We can't make vChecks in the inner loop because we want to measure
49+
// the cost of getting the memory to each thread and we might get the same
50+
// memory
51+
control.Add(vChecks);
52+
}
53+
// control waits for completion by RAII, but
54+
// it is done explicitly here for clarity
55+
control.Wait();
56+
}
57+
tg.interrupt_all();
58+
tg.join_all();
59+
}
60+
61+
// This Benchmark tests the CheckQueue with a slightly realistic workload,
62+
// where checks all contain a prevector that is indirect 50% of the time
63+
// and there is a little bit of work done between calls to Add.
64+
static void CCheckQueueSpeedPrevectorJob(benchmark::State& state)
65+
{
66+
struct PrevectorJob {
67+
prevector<PREVECTOR_SIZE, uint8_t> p;
68+
PrevectorJob(){
69+
}
70+
PrevectorJob(FastRandomContext& insecure_rand){
71+
p.resize(insecure_rand.rand32() % (PREVECTOR_SIZE*2));
72+
}
73+
bool operator()()
74+
{
75+
return true;
76+
}
77+
void swap(PrevectorJob& x){p.swap(x.p);};
78+
};
79+
CCheckQueue<PrevectorJob> queue {QUEUE_BATCH_SIZE};
80+
boost::thread_group tg;
81+
for (auto x = 0; x < std::max(MIN_CORES, GetNumCores()); ++x) {
82+
tg.create_thread([&]{queue.Thread();});
83+
}
84+
while (state.KeepRunning()) {
85+
// Make insecure_rand here so that each iteration is identical.
86+
FastRandomContext insecure_rand(true);
87+
CCheckQueueControl<PrevectorJob> control(&queue);
88+
std::vector<std::vector<PrevectorJob>> vBatches(BATCHES);
89+
for (auto& vChecks : vBatches) {
90+
vChecks.reserve(BATCH_SIZE);
91+
for (size_t x = 0; x < BATCH_SIZE; ++x)
92+
vChecks.emplace_back(insecure_rand);
93+
control.Add(vChecks);
94+
}
95+
// control waits for completion by RAII, but
96+
// it is done explicitly here for clarity
97+
control.Wait();
98+
}
99+
tg.interrupt_all();
100+
tg.join_all();
101+
}
102+
BENCHMARK(CCheckQueueSpeed);
103+
BENCHMARK(CCheckQueueSpeedPrevectorJob);

0 commit comments

Comments
 (0)