`std :: chrono`时钟与`boost :: xtime`的比较

时间:2019-02-13 21:01:45

标签: c++ c++11 boost timer

在各种平台上的怪癖和常规属性方面,C ++ 11 std::chronosteady_clock的时钟与high_resolution_clock的比较如何?

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

  • 分辨率:C ++ 11标准似乎不能保证任何分辨率;这些时钟的“现实”分辨率是多少? system_clock在同一系统上如何运作?

  • 最长持续时间:我知道例如在具有32位boost::xtime_get()和1 MHz标称时钟分辨率的系统上,clock()在大约一个小时后发生故障。 (是的,我知道clock_t的工作应该有所不同。)C ++ 11标准时钟在所有已知平台上能否应付几天甚至几周的持续时间?

    < / li>
  • 任何其他已知问题或令人惊讶的怪癖(编辑:clock()个时钟或std::chrono个)

2 个答案:

答案 0 :(得分:2)

  

在各种平台上的怪癖和常规属性方面,C ++ 11 std :: chrono时钟稳定时钟和high_resolution_clock与boost :: xtime :: xtime_get()相比如何?

任何计时库都只能交付底层操作系统/硬件组合可以交付的东西-句号。

即使库API承诺了纳秒级的分辨率,也不意味着底层的OS /硬件可以提供这种精度。因此最终,计时API无法改善平台的质量。

boost::xtime基本上是C(随后是C ++)将其标准化为timespec的标准。这是{second, nanosecond}对,根据标准C标头中使用的功能,它们既可以用作时间点,也可以用作持续时间。尽管对Boost头的快速调查似乎只是将xtime用作一个时间点(我可能会错过一些东西)。

timespec已有很长的使用历史,尤其是在POSIX系统中。它在POSIX系统上的存在时间比std::chrono更长,timespec是2008年设计的,并在C ++ 11(2011)中进行了标准化。

xtimetimespec)的范围通常大于宇宙的年龄。尽管在无法提供64位整数类型的系统上,timespec的范围将明显更小:+/- 68年,通常将其用作时间点集中在1970年左右。

如上所述,chrono 所有平台上发布纳秒精度,但只会提供基础平台可以提供的精度。

chrono为时间点和持续时间提供单独类型。这有助于在编译时捕获错误。例如,如果您将两个时间点加在一起,则不会编译。今天上午9点+今天上午7点是荒谬的。但是,如果减去两个时间点,则很有意义,并返回一个单独的类型:持续时间。今天上午9点-今天上午7点是2个小时。

chrono为持续时间和时间点提供了多种类型,它们的精度和表示形式都可能不同。 “内置”持续时间为纳秒,微秒,毫秒,秒,分钟和小时,每个持续时间都用带符号的整数类型表示(该列表在C ++ 2a规范草案中进行了扩展)。但是您可以使用自己的精度和表示形式(例如浮点数或安全整数库)创建自己的持续时间类型。

任何给定平台的now()的实现者都可以公布平台“ now()”功能的精度。即它不必总是十亿分之一秒,也可以是微秒或其他单位。不要求供应商诚实,但通常是。客户可以在编译时以编程方式查询chrono的返回类型的精度(毕竟这是C ++)。

{count of units}数据结构是xtime,而不是{seconds, nanoseconds} chrono数据结构。对于{count of units},持续时间和时间点都是如此,即使它们是不同的类型。

{seconds, nanoseconds}布局比sizeof布局具有以下优势:

  • 有一个较小的system_clock::time_point的机会。 xtime通常为64位,而xtime通常为128位。这确实为chrono提供了更好的范围。但是xtime库也可以与128位整数类型一起使用,该整数类型随后的范围将比chrono更大。

  • 客户可以使用xtime进行大小/范围权衡。 {count}客户得到他们所得到的。

  • {seconds, nanoseconds}相比,与{seconds, nanoseconds}数据结构相比,算术运算更快/更高效且更容易编程。这样会导致代码更小,更快,并且通常没有更多错误(用sizeof表示的负值是一个持续的恐怖故事)。

  • 对于给定的{count}和精度,使用{seconds, nanoseconds}数据结构总是可以获得比high_resolution_clock这样的多字段数据结构更大的范围。

  • p>
  

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

实际上,steady_clock始终是system_clocksteady_clock的类型别名。取决于平台。我的建议是只使用system_clocklibc++/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 ,以便您知道要处理的内容。

  

解决方案:C ++ 11标准似乎不能保证任何分辨率;这些时钟的“现实”分辨率是什么?

广告的分辨率为:

xtime

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

  

在所有已知平台上,C ++ 11标准时钟能否满足几天甚至几周的持续时间?

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

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

  

任何其他已知问题或令人惊讶的怪癖

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

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

答案 1 :(得分:0)

一些第一手和第二手结果测试sleep_for的行为,持续时间为1毫秒:

以下平台至少在平均水平上(超过1000次迭代)趋于“过度睡眠”:

  • 用于Linux / g ++的Windows子系统(1.8毫秒,显然有开销)
  • 正版Ubuntu / g ++(1.1毫秒)
  • FreeBSD / clang(1.1毫秒)
  • Wingwin / g ++(16毫秒,显然最少)
  • OS X(Darwin)/ g ++ / POSIX线程模型(1.2 ms)

到目前为止,似乎没有一个平台平均会“睡眠不足”。