8
8
#include < assert.h>
9
9
#include < iostream>
10
10
#include < iomanip>
11
- #include < sys/time.h>
12
11
13
12
benchmark::BenchRunner::BenchmarkMap &benchmark::BenchRunner::benchmarks () {
14
13
static std::map<std::string, benchmark::BenchFunction> benchmarks_map;
15
14
return benchmarks_map;
16
15
}
17
16
18
- static double gettimedouble (void ) {
19
- struct timeval tv;
20
- gettimeofday (&tv, nullptr );
21
- return tv.tv_usec * 0.000001 + tv.tv_sec ;
22
- }
23
-
24
17
benchmark::BenchRunner::BenchRunner (std::string name, benchmark::BenchFunction func)
25
18
{
26
19
benchmarks ().insert (std::make_pair (name, func));
27
20
}
28
21
29
22
void
30
- benchmark::BenchRunner::RunAll (double elapsedTimeForOne)
23
+ benchmark::BenchRunner::RunAll (benchmark::duration elapsedTimeForOne)
31
24
{
32
25
perf_init ();
33
- std::cout << " #Benchmark" << " ," << " count" << " ," << " min" << " ," << " max" << " ," << " average" << " ,"
26
+ std::cout << " #Benchmark" << " ," << " count" << " ," << " min(ns) " << " ," << " max(ns) " << " ," << " average(ns) " << " ,"
34
27
<< " min_cycles" << " ," << " max_cycles" << " ," << " average_cycles" << " \n " ;
35
28
36
29
for (const auto &p: benchmarks ()) {
@@ -46,16 +39,17 @@ bool benchmark::State::KeepRunning()
46
39
++count;
47
40
return true ;
48
41
}
49
- double now;
42
+ time_point now;
43
+
50
44
uint64_t nowCycles;
51
45
if (count == 0 ) {
52
- lastTime = beginTime = now = gettimedouble ();
46
+ lastTime = beginTime = now = clock::now ();
53
47
lastCycles = beginCycles = nowCycles = perf_cpucycles ();
54
48
}
55
49
else {
56
- now = gettimedouble ();
57
- double elapsed = now - lastTime;
58
- double elapsedOne = elapsed / (countMask + 1 );
50
+ now = clock::now ();
51
+ auto elapsed = now - lastTime;
52
+ auto elapsedOne = elapsed / (countMask + 1 );
59
53
if (elapsedOne < minTime) minTime = elapsedOne;
60
54
if (elapsedOne > maxTime) maxTime = elapsedOne;
61
55
@@ -70,8 +64,8 @@ bool benchmark::State::KeepRunning()
70
64
// The restart avoids including the overhead of this code in the measurement.
71
65
countMask = ((countMask<<3 )|7 ) & ((1LL <<60 )-1 );
72
66
count = 0 ;
73
- minTime = std::numeric_limits< double > ::max ();
74
- maxTime = std::numeric_limits< double >:: min ();
67
+ minTime = duration ::max ();
68
+ maxTime = duration::zero ();
75
69
minCycles = std::numeric_limits<uint64_t >::max ();
76
70
maxCycles = std::numeric_limits<uint64_t >::min ();
77
71
return true ;
@@ -94,9 +88,13 @@ bool benchmark::State::KeepRunning()
94
88
assert (count != 0 && " count == 0 => (now == 0 && beginTime == 0) => return above" );
95
89
96
90
// Output results
97
- double average = (now-beginTime)/count;
91
+ // Duration casts are only necessary here because hardware with sub-nanosecond clocks
92
+ // will lose precision.
93
+ int64_t min_elapsed = std::chrono::duration_cast<std::chrono::nanoseconds>(minTime).count ();
94
+ int64_t max_elapsed = std::chrono::duration_cast<std::chrono::nanoseconds>(maxTime).count ();
95
+ int64_t avg_elapsed = std::chrono::duration_cast<std::chrono::nanoseconds>((now-beginTime)/count).count ();
98
96
int64_t averageCycles = (nowCycles-beginCycles)/count;
99
- std::cout << std::fixed << std::setprecision (15 ) << name << " ," << count << " ," << minTime << " ," << maxTime << " ," << average << " ,"
97
+ std::cout << std::fixed << std::setprecision (15 ) << name << " ," << count << " ," << min_elapsed << " ," << max_elapsed << " ," << avg_elapsed << " ,"
100
98
<< minCycles << " ," << maxCycles << " ," << averageCycles << " \n " ;
101
99
std::cout.copyfmt (std::ios (nullptr ));
102
100
0 commit comments