问题
Running on Linux (uname says:)
Linux 2.6.32-431.29.2.el6.x86_64 #1 SMP Sun Jul 27 15:55:46 EDT 2014 x86_64 x86_64 x86_64 GNU/Linux
My tests show that clock_gettime calls with a clock id of CLOCK_MONOTONIC_COARSE are an order of magnitude faster than calls that use a clock id CLOCK_MONOTONIC.
Here's a sample output from a test run which called clock_gettime one million times in a tight loop and measured the lapsed time in milliseconds:
CLOCK_MONOTONIC lapse 795
CLOCK_MONOTONIC_COARSE lapse 27
This pleases me and makes the profiler results look better, however I was hoping that I could use std::chrono or boost::chrono for portability and standard conformance without sacrificing this speed. Unfortunately I haven't found any way to convince chrono (either one) to use CLOCK_MONOTONIC_COARSE when it's available. I tried chrono::steady_clock, but the results are comparable to the CLOCK_MONOTONIC values.
Is there a way to specify to chrono that you are willing to sacrifice precision for speed?
回答1:
As Howard said it's simple make your own clock - a type conforming to the C++11 Clock requirements - that uses CLOCK_MONOTONIC_COARSE
when it's available and CLOCK_MONOTONIC
otherwise (Live at Coliru):
class fast_monotonic_clock {
public:
using duration = std::chrono::nanoseconds;
using rep = duration::rep;
using period = duration::period;
using time_point = std::chrono::time_point<fast_monotonic_clock>;
static constexpr bool is_steady = true;
static time_point now() noexcept;
static duration get_resolution() noexcept;
private:
static clockid_t clock_id();
static clockid_t test_coarse_clock();
static duration convert(const timespec&);
};
inline clockid_t fast_monotonic_clock::test_coarse_clock() {
struct timespec t;
if (clock_gettime(CLOCK_MONOTONIC_COARSE, &t) == 0) {
return CLOCK_MONOTONIC_COARSE;
} else {
return CLOCK_MONOTONIC;
}
}
clockid_t fast_monotonic_clock::clock_id() {
static clockid_t the_clock = test_coarse_clock();
return the_clock;
}
inline auto fast_monotonic_clock::convert(const timespec& t) -> duration {
return std::chrono::seconds(t.tv_sec) + std::chrono::nanoseconds(t.tv_nsec);
}
auto fast_monotonic_clock::now() noexcept -> time_point {
struct timespec t;
const auto result = clock_gettime(clock_id(), &t);
assert(result == 0);
return time_point{convert(t)};
}
auto fast_monotonic_clock::get_resolution() noexcept -> duration {
struct timespec t;
const auto result = clock_getres(clock_id(), &t);
assert(result == 0);
return convert(t);
}
来源:https://stackoverflow.com/questions/26003413/stdchrono-or-boostchrono-support-for-clock-monotonic-coarse