@ -8,29 +8,22 @@
# include <assert.h>
# include <iostream>
# include <iomanip>
# include <sys/time.h>
benchmark : : BenchRunner : : BenchmarkMap & benchmark : : BenchRunner : : benchmarks ( ) {
static std : : map < std : : string , benchmark : : BenchFunction > benchmarks_map ;
return benchmarks_map ;
}
static double gettimedouble ( void ) {
struct timeval tv ;
gettimeofday ( & tv , nullptr ) ;
return tv . tv_usec * 0.000001 + tv . tv_sec ;
}
benchmark : : BenchRunner : : BenchRunner ( std : : string name , benchmark : : BenchFunction func )
{
benchmarks ( ) . insert ( std : : make_pair ( name , func ) ) ;
}
void
benchmark : : BenchRunner : : RunAll ( double elapsedTimeForOne )
benchmark : : BenchRunner : : RunAll ( benchmark : : duration elapsedTimeForOne )
{
perf_init ( ) ;
std : : cout < < " #Benchmark " < < " , " < < " count " < < " , " < < " min " < < " , " < < " max " < < " , " < < " average " < < " , "
std : : cout < < " #Benchmark " < < " , " < < " count " < < " , " < < " min (ns) " < < " , " < < " max (ns) " < < " , " < < " average (ns) " < < " , "
< < " min_cycles " < < " , " < < " max_cycles " < < " , " < < " average_cycles " < < " \n " ;
for ( const auto & p : benchmarks ( ) ) {
@ -46,16 +39,17 @@ bool benchmark::State::KeepRunning()
+ + count ;
return true ;
}
double now ;
time_point now ;
uint64_t nowCycles ;
if ( count = = 0 ) {
lastTime = beginTime = now = gettimedouble ( ) ;
lastTime = beginTime = now = clock: : now ( ) ;
lastCycles = beginCycles = nowCycles = perf_cpucycles ( ) ;
}
else {
now = gettimedouble ( ) ;
double elapsed = now - lastTime ;
double elapsedOne = elapsed / ( countMask + 1 ) ;
now = clock: : now ( ) ;
auto elapsed = now - lastTime ;
auto elapsedOne = elapsed / ( countMask + 1 ) ;
if ( elapsedOne < minTime ) minTime = elapsedOne ;
if ( elapsedOne > maxTime ) maxTime = elapsedOne ;
@ -70,8 +64,8 @@ bool benchmark::State::KeepRunning()
// The restart avoids including the overhead of this code in the measurement.
countMask = ( ( countMask < < 3 ) | 7 ) & ( ( 1LL < < 60 ) - 1 ) ;
count = 0 ;
minTime = std: : numeric_limits < double > : : max ( ) ;
maxTime = std: : numeric_limits < double > : : min ( ) ;
minTime = duration : : max ( ) ;
maxTime = duration: : zero ( ) ;
minCycles = std : : numeric_limits < uint64_t > : : max ( ) ;
maxCycles = std : : numeric_limits < uint64_t > : : min ( ) ;
return true ;
@ -94,9 +88,13 @@ bool benchmark::State::KeepRunning()
assert ( count ! = 0 & & " count == 0 => (now == 0 && beginTime == 0) => return above " ) ;
// Output results
double average = ( now - beginTime ) / count ;
// Duration casts are only necessary here because hardware with sub-nanosecond clocks
// will lose precision.
int64_t min_elapsed = std : : chrono : : duration_cast < std : : chrono : : nanoseconds > ( minTime ) . count ( ) ;
int64_t max_elapsed = std : : chrono : : duration_cast < std : : chrono : : nanoseconds > ( maxTime ) . count ( ) ;
int64_t avg_elapsed = std : : chrono : : duration_cast < std : : chrono : : nanoseconds > ( ( now - beginTime ) / count ) . count ( ) ;
int64_t averageCycles = ( nowCycles - beginCycles ) / count ;
std : : cout < < std : : fixed < < std : : setprecision ( 15 ) < < name < < " , " < < count < < " , " < < minTime < < " , " < < maxTime < < " , " < < average < < " , "
std : : cout < < std : : fixed < < std : : setprecision ( 15 ) < < name < < " , " < < count < < " , " < < min _elapsed < < " , " < < max _elapsed < < " , " < < av g_elapsed < < " , "
< < minCycles < < " , " < < maxCycles < < " , " < < averageCycles < < " \n " ;
std : : cout . copyfmt ( std : : ios ( nullptr ) ) ;