Changeset View
Changeset View
Standalone View
Standalone View
src/bench/checkqueue.cpp
Show All 17 Lines | |||||
static const size_t BATCHES = 101; | static const size_t BATCHES = 101; | ||||
static const size_t BATCH_SIZE = 30; | static const size_t BATCH_SIZE = 30; | ||||
static const int PREVECTOR_SIZE = 28; | static const int PREVECTOR_SIZE = 28; | ||||
static const size_t QUEUE_BATCH_SIZE = 128; | static const size_t QUEUE_BATCH_SIZE = 128; | ||||
// This Benchmark tests the CheckQueue with a slightly realistic workload, where | // This Benchmark tests the CheckQueue with a slightly realistic workload, where | ||||
// checks all contain a prevector that is indirect 50% of the time and there is | // checks all contain a prevector that is indirect 50% of the time and there is | ||||
// a little bit of work done between calls to Add. | // a little bit of work done between calls to Add. | ||||
static void CCheckQueueSpeedPrevectorJob(benchmark::State &state) { | static void CCheckQueueSpeedPrevectorJob(benchmark::Bench &bench) { | ||||
const ECCVerifyHandle verify_handle; | const ECCVerifyHandle verify_handle; | ||||
ECC_Start(); | ECC_Start(); | ||||
struct PrevectorJob { | struct PrevectorJob { | ||||
prevector<PREVECTOR_SIZE, uint8_t> p; | prevector<PREVECTOR_SIZE, uint8_t> p; | ||||
PrevectorJob() {} | PrevectorJob() {} | ||||
explicit PrevectorJob(FastRandomContext &insecure_rand) { | explicit PrevectorJob(FastRandomContext &insecure_rand) { | ||||
p.resize(insecure_rand.randrange(PREVECTOR_SIZE * 2)); | p.resize(insecure_rand.randrange(PREVECTOR_SIZE * 2)); | ||||
} | } | ||||
bool operator()() { return true; } | bool operator()() { return true; } | ||||
void swap(PrevectorJob &x) { p.swap(x.p); }; | void swap(PrevectorJob &x) { p.swap(x.p); }; | ||||
}; | }; | ||||
CCheckQueue<PrevectorJob> queue{QUEUE_BATCH_SIZE}; | CCheckQueue<PrevectorJob> queue{QUEUE_BATCH_SIZE}; | ||||
boost::thread_group tg; | boost::thread_group tg; | ||||
for (auto x = 0; x < std::max(MIN_CORES, GetNumCores()); ++x) { | for (auto x = 0; x < std::max(MIN_CORES, GetNumCores()); ++x) { | ||||
tg.create_thread([&] { queue.Thread(); }); | tg.create_thread([&] { queue.Thread(); }); | ||||
} | } | ||||
while (state.KeepRunning()) { | |||||
// Make insecure_rand here so that each iteration is identical. | // create all the data once, then submit copies in the benchmark. | ||||
FastRandomContext insecure_rand(true); | FastRandomContext insecure_rand(true); | ||||
CCheckQueueControl<PrevectorJob> control(&queue); | |||||
std::vector<std::vector<PrevectorJob>> vBatches(BATCHES); | std::vector<std::vector<PrevectorJob>> vBatches(BATCHES); | ||||
for (auto &vChecks : vBatches) { | for (auto &vChecks : vBatches) { | ||||
vChecks.reserve(BATCH_SIZE); | vChecks.reserve(BATCH_SIZE); | ||||
for (size_t x = 0; x < BATCH_SIZE; ++x) { | for (size_t x = 0; x < BATCH_SIZE; ++x) { | ||||
vChecks.emplace_back(insecure_rand); | vChecks.emplace_back(insecure_rand); | ||||
} | } | ||||
} | |||||
bench.minEpochIterations(10) | |||||
.batch(BATCH_SIZE * BATCHES) | |||||
.unit("job") | |||||
.run([&] { | |||||
// Make insecure_rand here so that each iteration is identical. | |||||
CCheckQueueControl<PrevectorJob> control(&queue); | |||||
std::vector<std::vector<PrevectorJob>> vBatches(BATCHES); | |||||
for (auto &vChecks : vBatches) { | |||||
control.Add(vChecks); | control.Add(vChecks); | ||||
} | } | ||||
// control waits for completion by RAII, but it is done explicitly here | // control waits for completion by RAII, but it is done explicitly | ||||
// for clarity | // here for clarity | ||||
control.Wait(); | control.Wait(); | ||||
} | }); | ||||
tg.interrupt_all(); | tg.interrupt_all(); | ||||
tg.join_all(); | tg.join_all(); | ||||
ECC_Stop(); | ECC_Stop(); | ||||
} | } | ||||
BENCHMARK(CCheckQueueSpeedPrevectorJob, 1400); | BENCHMARK(CCheckQueueSpeedPrevectorJob); |