Skip to content

Commit

Permalink
Support very-fast-running benchmarks
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
gavinandresen committed Sep 30, 2015
1 parent 535ed92 commit 7072c54
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 4 deletions.
2 changes: 1 addition & 1 deletion src/Makefile.bench.include
Expand Up @@ -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 = \
Expand Down
18 changes: 18 additions & 0 deletions src/bench/MilliSleep.cpp → src/bench/Examples.cpp
Expand Up @@ -6,6 +6,8 @@
#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()) {
Expand All @@ -14,3 +16,19 @@ static void Sleep100ms(benchmark::State& state)
}

BENCHMARK(Sleep100ms);

// Extremely fast-running benchmark:
#include <math.h>

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);
14 changes: 11 additions & 3 deletions src/bench/bench.cpp
Expand Up @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions src/bench/bench.h
Expand Up @@ -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<double>::max();
maxTime = std::numeric_limits<double>::min();
timeCheckCount = 1;
}
bool KeepRunning();
};
Expand Down

0 comments on commit 7072c54

Please sign in to comment.