在各种平台上的怪癖和常规属性方面,C ++ 11 std::chrono
和steady_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标准时钟在所有已知平台上能否应付几天甚至几周的持续时间?
任何其他已知问题或令人惊讶的怪癖(编辑:clock()
个时钟或std::chrono
个)?
答案 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)中进行了标准化。
xtime
(timespec
)的范围通常大于宇宙的年龄。尽管在无法提供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
这样的多字段数据结构更大的范围。
该标准不能保证high_resolution_clock是稳定的(明确提到它可能是system_clock的别名),因此这是一个需要注意的陷阱。
实际上,steady_clock
始终是system_clock
或steady_clock
的类型别名。取决于平台。我的建议是只使用system_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
,以便您知道要处理的内容。
解决方案: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次迭代)趋于“过度睡眠”:
到目前为止,似乎没有一个平台平均会“睡眠不足”。