From 7072c544b52774ac5a22835121e8e2747ad61158 Mon Sep 17 00:00:00 2001 From: Gavin Andresen Date: Tue, 29 Sep 2015 17:17:24 -0400 Subject: Support very-fast-running benchmarks Avoid calling gettimeofday every time through the benchmarking loop, by keeping track of how long each loop takes and doubling the number of iterations done between time checks when they take less than 1/16'th of the total elapsed time. --- src/Makefile.bench.include | 2 +- src/bench/Examples.cpp | 34 ++++++++++++++++++++++++++++++++++ src/bench/MilliSleep.cpp | 16 ---------------- src/bench/bench.cpp | 14 +++++++++++--- src/bench/bench.h | 2 ++ 5 files changed, 48 insertions(+), 20 deletions(-) create mode 100644 src/bench/Examples.cpp delete mode 100644 src/bench/MilliSleep.cpp diff --git a/src/Makefile.bench.include b/src/Makefile.bench.include index 126e3a102f..61fe9e287d 100644 --- a/src/Makefile.bench.include +++ b/src/Makefile.bench.include @@ -7,7 +7,7 @@ bench_bench_bitcoin_SOURCES = \ bench/bench_bitcoin.cpp \ bench/bench.cpp \ bench/bench.h \ - bench/MilliSleep.cpp + bench/Examples.cpp bench_bench_bitcoin_CPPFLAGS = $(BITCOIN_INCLUDES) $(EVENT_CLFAGS) $(EVENT_PTHREADS_CFLAGS) -I$(builddir)/bench/ bench_bench_bitcoin_LDADD = \ diff --git a/src/bench/Examples.cpp b/src/bench/Examples.cpp new file mode 100644 index 0000000000..b6b020a971 --- /dev/null +++ b/src/bench/Examples.cpp @@ -0,0 +1,34 @@ +// Copyright (c) 2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "bench.h" +#include "main.h" +#include "utiltime.h" + +// Sanity test: this should loop ten times, and +// min/max/average should be close to 100ms. +static void Sleep100ms(benchmark::State& state) +{ + while (state.KeepRunning()) { + MilliSleep(100); + } +} + +BENCHMARK(Sleep100ms); + +// Extremely fast-running benchmark: +#include + +volatile double sum = 0.0; // volatile, global so not optimized away + +static void Trig(benchmark::State& state) +{ + double d = 0.01; + while (state.KeepRunning()) { + sum += sin(d); + d += 0.000001; + } +} + +BENCHMARK(Trig); diff --git a/src/bench/MilliSleep.cpp b/src/bench/MilliSleep.cpp deleted file mode 100644 index 991397a234..0000000000 --- a/src/bench/MilliSleep.cpp +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) 2015 The Bitcoin Core developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include "bench.h" -#include "main.h" -#include "utiltime.h" - -static void Sleep100ms(benchmark::State& state) -{ - while (state.KeepRunning()) { - MilliSleep(100); - } -} - -BENCHMARK(Sleep100ms); diff --git a/src/bench/bench.cpp b/src/bench/bench.cpp index 5720807609..89c3b0cc2a 100644 --- a/src/bench/bench.cpp +++ b/src/bench/bench.cpp @@ -36,14 +36,22 @@ BenchRunner::RunAll(double elapsedTimeForOne) bool State::KeepRunning() { - double now = gettimedouble(); + double now; if (count == 0) { - beginTime = now; + beginTime = now = gettimedouble(); } else { - double elapsedOne = now - lastTime; + // timeCheckCount is used to avoid calling gettime most of the time, + // so benchmarks that run very quickly get consistent results. + if ((count+1)%timeCheckCount != 0) { + ++count; + return true; // keep going + } + now = gettimedouble(); + double elapsedOne = (now - lastTime)/timeCheckCount; if (elapsedOne < minTime) minTime = elapsedOne; if (elapsedOne > maxTime) maxTime = elapsedOne; + if (elapsedOne*timeCheckCount < maxElapsed/16) timeCheckCount *= 2; } lastTime = now; ++count; diff --git a/src/bench/bench.h b/src/bench/bench.h index fee9b8c38d..bf591a2be6 100644 --- a/src/bench/bench.h +++ b/src/bench/bench.h @@ -41,10 +41,12 @@ namespace benchmark { double beginTime; double lastTime, minTime, maxTime; int64_t count; + int64_t timeCheckCount; public: State(std::string _name, double _maxElapsed) : name(_name), maxElapsed(_maxElapsed), count(0) { minTime = std::numeric_limits::max(); maxTime = std::numeric_limits::min(); + timeCheckCount = 1; } bool KeepRunning(); }; -- cgit v1.2.3