1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
|
/*
* Created by Phil on 05/08/2013.
* Copyright 2013 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#include "catch_timer.h"
#include <chrono>
static const uint64_t nanosecondsInSecond = 1000000000;
namespace Catch {
auto getCurrentNanosecondsSinceEpoch() -> uint64_t {
return std::chrono::duration_cast<std::chrono::nanoseconds>( std::chrono::high_resolution_clock::now().time_since_epoch() ).count();
}
namespace {
auto estimateClockResolution() -> uint64_t {
uint64_t sum = 0;
static const uint64_t iterations = 1000000;
auto startTime = getCurrentNanosecondsSinceEpoch();
for( std::size_t i = 0; i < iterations; ++i ) {
uint64_t ticks;
uint64_t baseTicks = getCurrentNanosecondsSinceEpoch();
do {
ticks = getCurrentNanosecondsSinceEpoch();
} while( ticks == baseTicks );
auto delta = ticks - baseTicks;
sum += delta;
// If we have been calibrating for over 3 seconds -- the clock
// is terrible and we should move on.
// TBD: How to signal that the measured resolution is probably wrong?
if (ticks > startTime + 3 * nanosecondsInSecond) {
return sum / ( i + 1u );
}
}
// We're just taking the mean, here. To do better we could take the std. dev and exclude outliers
// - and potentially do more iterations if there's a high variance.
return sum/iterations;
}
}
auto getEstimatedClockResolution() -> uint64_t {
static auto s_resolution = estimateClockResolution();
return s_resolution;
}
void Timer::start() {
m_nanoseconds = getCurrentNanosecondsSinceEpoch();
}
auto Timer::getElapsedNanoseconds() const -> uint64_t {
return getCurrentNanosecondsSinceEpoch() - m_nanoseconds;
}
auto Timer::getElapsedMicroseconds() const -> uint64_t {
return getElapsedNanoseconds()/1000;
}
auto Timer::getElapsedMilliseconds() const -> unsigned int {
return static_cast<unsigned int>(getElapsedMicroseconds()/1000);
}
auto Timer::getElapsedSeconds() const -> double {
return getElapsedMicroseconds()/1000000.0;
}
} // namespace Catch
|