Dal*_*son 3 c++ time boost c++11 c++-chrono
在 Linux 上运行(uname 说:)
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
Run Code Online (Sandbox Code Playgroud)
我的测试表明,时钟 ID 为 CLOCK_MONOTONIC_COARSE 的 clock_gettime 调用比使用时钟 ID CLOCK_MONOTONIC 的调用快一个数量级。
这是一个测试运行的示例输出,它在紧密循环中调用 clock_gettime 一百万次,并以毫秒为单位测量经过的时间:
CLOCK_MONOTONIC lapse 795
CLOCK_MONOTONIC_COARSE lapse 27
Run Code Online (Sandbox Code Playgroud)
这让我很高兴并使分析器的结果看起来更好,但是我希望我可以使用 std::chrono 或 boost::chrono 来实现便携性和标准一致性,而不会牺牲这个速度。不幸的是,我还没有找到任何方法来说服 chrono(任一)在可用时使用 CLOCK_MONOTONIC_COARSE。我尝试了 chrono::steady_clock,但结果与 CLOCK_MONOTONIC 值相当。
有没有办法指定你愿意为了速度而牺牲精度的chrono?
正如霍华德所说,制作自己的时钟很简单 - 一种符合 C++11时钟要求的类型 -CLOCK_MONOTONIC_COARSE在可用时使用,CLOCK_MONOTONIC否则使用(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);
}
Run Code Online (Sandbox Code Playgroud)