就各种平台上的怪癖和常规属性而言,C++ 11 std::chrono时钟steady_clockhigh_resolution_clock如何与boost::xtime::xtime_get()比较?

该标准不保证high_resolution_clock稳定(它明确提到它可能是system_clock的别名),因此这是一个需要注意的陷阱。我想到的其他属性:

  • 分辨率:C++ 11标准似乎不能保证任何分辨率。这些时钟的“真实”分辨率是多少? boost::xtime_get()在同一系统上如何运作?
  • 最大持续时间:我知道例如在具有32位clock()和1 MHz标称时钟分辨率的系统上,clock_t在大约一个小时后发生故障。 (是的,我知道clock()应该可以做一些不同的工作。)C++ 11标准时钟在所有已知平台上能否应付几天甚至几周的持续时间?
  • 是否还有其他已知问题或令人惊讶的怪癖(编辑:std::chrono clocks或boost::xtime::xtime_get)?
  • 最佳答案



    任何定时库只能提供基础操作系统/硬件组合可以提供的功能-句号停止。

    即使库API promise 了纳秒级的分辨率,也不意味着底层的OS /硬件可以提供这种精度。因此最终,计时API无法改善平台的质量。
    boost::xtime基本上是C(以及后来的C++)标准化为timespec的内容。这是一个{second, nanosecond}对,它既用作时间点,又用作持续时间,具体取决于它在标准C header 中使用的功能。尽管对boost头的快速调查似乎只是将xtime用作一个时间点(我可能会错过一些东西)。
    timespec已有很长的使用历史,尤其是在POSIX系统中。它在POSIX系统上的存在时间比std::chrono更长,后者是2008年设计的,并在C++ 11(2011)中进行了标准化。
    timespec(xtime)的范围通常大于宇宙的年龄。尽管在无法提供64位整数类型的系统上,timespec的范围将显着缩小:+/- 68年,通常将其用作时间点以1970年为中心。

    如上所述,timespec在所有平台上公布纳秒精度,但仅提供基础平台可以提供的精度。
    chrono提供时间点和持续时间的不同类型。这有助于在编译时捕获错误。例如,如果将两个时间点加在一起,则不会编译。今天上午9点+今天上午7点是荒谬的。但是,如果您减去两个时间点,则很有意义并返回一个单独的类型:持续时间。今天上午9点-今天上午7点是2个小时。
    chrono在持续时间和时间点上提供多种类型,它们的精度和表示形式都可能不同。 “内置”持续时间为纳秒,微秒,毫秒,秒,分钟和小时,每个持续时间都用带符号的整数类型表示(该列表在C++ 20规范中进行了扩展)。但是您可以使用自己的精度和表示形式创建自己的持续时间类型(例如,浮点数或安全整数库)。

    任何给定平台的chrono的实现者都可以公布平台“now()”函数的精度。即它不必总是十亿分之一秒,也可以是微秒或其他单位。不要求卖方诚实,但通常是。客户端可以在编译时以编程方式查询now()的返回类型的精度(毕竟这是C++)。
    chrono数据结构是{count of units},与xtime {seconds, nanoseconds}数据结构相反。对于chrono,持续时间和时间点均适用,即使这些是截然不同的类型。

    {count of units}布局相比,{seconds, nanoseconds}布局具有多个优点:

  • 有机会使用较小的sizeofsystem_clock::time_point通常为64位,而xtime通常为128位。这确实为xtime提供了更好的范围。但是,chrono库也可以与128位整数类型一起使用,该类型随后将具有比xtime更大的范围。
  • 客户可以使用chrono进行大小/范围权衡。 xtime客户端获得他们所获得的。
  • {count}相比,使用{seconds, nanoseconds}数据结构可以更快/更高效且更容易编程。这导致代码更小,更快,并且通常没有更多错误(用{seconds, nanoseconds}表示的负值是一个持续的恐怖故事)。
  • 对于给定的sizeof和精度,使用{count}数据结构始终可以获得比诸如{seconds, nanoseconds}的多字段数据结构更大的范围。



  • 实际上,high_resolution_clock始终是steady_clocksystem_clock的类型别名。取决于平台。我的建议是只使用steady_clocksystem_clock,这样您就知道要处理的内容。



    宣传的决议是:
    libc++/llvm:
    
    system_clock
        rep is long long : 64 bits
        period is 1/1,000,000
        is_steady is 0
    
    high_resolution_clock
        rep is long long : 64 bits
        period is 1/1,000,000,000
        is_steady is 1
    
    steady_clock
        rep is long long : 64 bits
        period is 1/1,000,000,000
        is_steady is 1
    
    high_resolution_clock is the same type as steady_clock
    
    libstdc++/gcc:
    
    system_clock
        rep is long : 64 bits
        period is 1/1,000,000,000
        is_steady is 0
    
    high_resolution_clock
        rep is long : 64 bits
        period is 1/1,000,000,000
        is_steady is 0
    
    steady_clock
        rep is long : 64 bits
        period is 1/1,000,000,000
        is_steady is 1
    
    high_resolution_clock is the same type as system_clock
    
    VS-2013:
    
    system_clock
        rep is __int64 : 64 bits
        period is 1/10,000,000
        is_steady is 0
    
    high_resolution_clock
        rep is __int64 : 64 bits
        period is 1/1,000,000,000
        is_steady is 1
    
    steady_clock
        rep is __int64 : 64 bits
        period is 1/1,000,000,000
        is_steady is 1
    
    high_resolution_clock is the same type as steady_clock
    

    由于我的开场白,对于任何给定的平台,“实际”分辨率很可能与xtime相同。



    是。甚至几个月甚至几年。

    您将要遇到的第一个持续时间限制是纳秒级分辨率。 chrono保证至少有一个64位带符号的整数表示形式,为您提供+ -292年的范围。当谈论system_clock时,此范围将集中在1970年。



    当在范围限制或附近限制操作时,chrono库可以轻松而无声地溢出。例如,如果将microseconds::max()nanoseconds::max()进行比较,您将遇到溢出并获得不确定的结果。发生这种情况是因为比较运算符将在进行比较之前首先将microseconds转换为nanoseconds,并且转换会溢出。

    充分避开持续时间和time_point范围限制。如果您必须处理它们,并且不确定如何处理,请查看Stackoverflow以获得答案。如果您的搜索不满意,请询问您所关心的特定问题。

    09-25 20:37