就各种平台上的怪癖和常规属性而言,C++ 11 std::chrono
时钟steady_clock
和high_resolution_clock
如何与boost::xtime::xtime_get()
比较?
该标准不保证high_resolution_clock
稳定(它明确提到它可能是system_clock
的别名),因此这是一个需要注意的陷阱。我想到的其他属性:
boost::xtime_get()
在同一系统上如何运作? 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}
布局具有多个优点:
sizeof
。 system_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_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
由于我的开场白,对于任何给定的平台,“实际”分辨率很可能与
xtime
相同。是。甚至几个月甚至几年。
您将要遇到的第一个持续时间限制是纳秒级分辨率。
chrono
保证至少有一个64位带符号的整数表示形式,为您提供+ -292年的范围。当谈论system_clock
时,此范围将集中在1970年。当在范围限制或附近限制操作时,
chrono
库可以轻松而无声地溢出。例如,如果将microseconds::max()
与nanoseconds::max()
进行比较,您将遇到溢出并获得不确定的结果。发生这种情况是因为比较运算符将在进行比较之前首先将microseconds
转换为nanoseconds
,并且转换会溢出。充分避开持续时间和time_point范围限制。如果您必须处理它们,并且不确定如何处理,请查看Stackoverflow以获得答案。如果您的搜索不满意,请询问您所关心的特定问题。