【问题标题】:Std::chrono or boost::chrono support for CLOCK_MONOTONIC_COARSE对 CLOCK_MONOTONIC_COARSE 的 Std::chrono 或 boost::chrono 支持
【发布时间】:2014-09-26 00:18:55
【问题描述】:

在 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

我的测试表明,时钟 ID 为 CLOCK_MONOTONIC_COARSE 的 clock_gettime 调用比使用时钟 ID CLOCK_MONOTONIC 的调用快一个数量级。

这是一个测试运行的示例输出,它在紧密循环中调用了一百万次clock_gettime,并以毫秒为单位测量了经过的时间:

CLOCK_MONOTONIC lapse 795
CLOCK_MONOTONIC_COARSE lapse 27

这让我很高兴,并使分析器结果看起来更好,但是我希望我可以使用 std::chrono 或 boost::chrono 来实现可移植性和标准一致性,而不会牺牲这个速度。不幸的是,我还没有找到任何方法来说服 chrono(任何一个)在可用时使用 CLOCK_MONOTONIC_COARSE。我尝试了 chrono::steady_clock,但结果与 CLOCK_MONOTONIC 值相当。

有没有办法指定 chrono 你愿意牺牲精度来换取速度?

【问题讨论】:

  • 您使用了std::chrono:: 中的哪一个?
  • @5gon12eder:我刚刚编辑了问题以表明我尝试了 std::chrono::steady_clock
  • 如果您了解CLOCK_MONOTONIC_COARSE的特点,您可以轻松地围绕它构建自己的自定义计时风格时钟。你只需要几个typedefs 和一个now() 函数。
  • 我刚刚检查了 GNU 实现中的chrono.cc,它只处理CLOCK_REALTIMECLOCK_MONOTONIC。甚至没有提供用于选择粗略时钟的宏。

标签: c++ c++11 boost time chrono


【解决方案1】:

作为Howard said,制作自己的时钟很简单——符合 C++11 Clock 要求的类型——在可用时使用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);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-05
    • 2014-03-23
    • 2017-09-02
    • 1970-01-01
    • 1970-01-01
    • 2023-01-11
    相关资源
    最近更新 更多