in src/benchmarks/benchmark.h [72:153]
void Run(size_t thread_count, uint64_t seconds_to_run,
AffinityPattern affinity, uint64_t dump_interval) {
threads_finished_ = 0;
threads_ready_ = 0;
start_running_ = false;
Setup(thread_count);
LARGE_INTEGER frequency;
QueryPerformanceFrequency(&frequency);
uint64_t ticks_per_second = frequency.QuadPart;
// Start threads
std::deque<std::thread> threads;
for(size_t i = 0; i < thread_count; ++i) {
threads.emplace_back(&Benchmark::entry, this, i, thread_count, affinity);
}
// Wait for threads to be ready
while(threads_ready_.load() < thread_count);
uint64_t unique_dump_id = __rdtsc();
if(dump_interval > 0) {
Dump(thread_count, 0, unique_dump_id, false);
}
VLOG(1) << "Starting benchmark.";
// Start the benchmark
LARGE_INTEGER counter;
QueryPerformanceCounter(&counter);
uint64_t start = counter.QuadPart;
start_running_.store(true, std::memory_order_release);
const int64_t end = start + ticks_per_second * seconds_to_run;
if(dump_interval > 0) {
uint64_t next_dump_ticks = ticks_per_second + start;
uint64_t next_dump_seconds = 1;
while(threads_finished_.load() < thread_count) {
Sleep(10);
QueryPerformanceCounter(&counter);
uint64_t now = counter.QuadPart;
if(end <= counter.QuadPart) {
is_shutdown_.store(true, std::memory_order_release);
break;
}
if(now < next_dump_ticks) continue;
// Collect metrics after the experiment end.
unique_dump_id = __rdtsc();
Dump(thread_count, now - start, unique_dump_id, false);
// 'Schedule' next dump.
next_dump_seconds += dump_interval;
next_dump_ticks = next_dump_seconds * ticks_per_second + start;
}
} else {
// Sleep the required amount of time before setting the shutdown flag.
::Sleep((DWORD)seconds_to_run * 1000);
is_shutdown_.store(true, std::memory_order_release);
// Wait for all threads to finish their workload
while(threads_finished_.load() < thread_count) {
::Sleep(10);
}
}
for(auto& thread : threads) {
thread.join();
}
while(0 == end_.load());
unique_dump_id = __rdtsc();
VLOG(1) << "Benchmark stopped.";
Dump(thread_count, end_ - start, unique_dump_id, true);
run_seconds_ = double(end_ - start) / double(ticks_per_second);
Teardown();
}