std::system_clock和std::steady_clock有什么区别?(举例说明不同的结果/行为将是很好的)。
如果我的目标是精确地测量函数的执行时间(就像基准),那么在std::system_clock、std::steady_clock和std::high_resolution_clock之间最好的选择是什么?
发布于 2012-11-07 04:54:57
来自N3376:
20.11.7.1时钟系统/1:
类
system_clock对象表示来自系统范围的实时时钟的挂钟时间.
20.11.7.2时钟稳定/1:
steady_clock类的对象表示时钟,其中time_point的值不会随着物理时间的推移而减少,而time_point的值相对于实时以稳定的速度前进。也就是说,钟是不可以调整的。
20.11.7.3时钟时间/1:
high_resolution_clock类的对象表示具有最短滴答周期的时钟。high_resolution_clock可以是system_clock或steady_clock的同义词。
例如,系统宽时钟可能会受到夏时制之类的影响,在这种情况下,将来某一时刻列出的实际时间实际上可能是过去的一个时间。(例如,在美国,秋天的时间向后移动一个小时,因此同一时间经历了“两次”)然而,steady_clock不允许受这些事情的影响。
在这种情况下,另一种思考“稳定”的方法是在20.11.3 time.clock.req/2表中定义的需求:
在表59中,
C1和C2表示时钟类型。t1和t2是由C1::now()返回的值,其中调用返回t1发生在调用返回t2之前,而这两个调用都发生在C1::time_point::max()之前。注意:这意味着C1没有在t1和t2之间转圈。-end注释表达式:C1::is_steady返回:const bool操作语义:如果truet1 <= t2总是真的,并且时钟滴答之间的时间是恒定的,则为false。
这就是他们之间的不同之处。
如果您想做基准测试,您最好的选择可能是std::high_resolution_clock,因为您的平台很可能对此时钟使用高分辨率计时器(例如QueryPerformanceCounter )。但是,如果您正在进行基准测试,那么您应该考虑在基准测试中使用特定于平台的定时器,因为不同的平台处理这个问题的方式不同。例如,一些平台可能提供一些方法来确定程序所需时钟的实际数量(独立于运行在同一CPU上的其他进程)。更好的是,把你的手放在一个真正的剖析器上,然后使用它。
发布于 2012-11-07 09:13:17
比利提供了一个很好的答案,基于国际标准化组织C++标准,我完全同意。然而,故事的另一面是真实的生活。现在看来,在流行编译器的实现中,这些时钟实际上并没有什么区别:
gcc 4.8:
#ifdef _GLIBCXX_USE_CLOCK_MONOTONIC
...
#else
typedef system_clock steady_clock;
#endif
typedef system_clock high_resolution_clock;Visual Studio 2012:
class steady_clock : public system_clock
{ // wraps monotonic clock
public:
static const bool is_monotonic = true; // retained
static const bool is_steady = true;
};
typedef system_clock high_resolution_clock;在gcc的情况下,您可以检查是否处理稳定的时钟,只需检查is_steady,并采取相应的行动。然而,VS2012似乎在这里欺骗了一点:-)
如果您需要高精度的时钟,我建议您现在编写符合C++11正式时钟接口的时钟,并等待实现赶上。这将比直接在代码中使用OS特定的API要好得多。对于Windows,您可以这样做:
// Self-made Windows QueryPerformanceCounter based C++11 API compatible clock
struct qpc_clock {
typedef std::chrono::nanoseconds duration; // nanoseconds resolution
typedef duration::rep rep;
typedef duration::period period;
typedef std::chrono::time_point<qpc_clock, duration> time_point;
static bool is_steady; // = true
static time_point now()
{
if(!is_inited) {
init();
is_inited = true;
}
LARGE_INTEGER counter;
QueryPerformanceCounter(&counter);
return time_point(duration(static_cast<rep>((double)counter.QuadPart / frequency.QuadPart *
period::den / period::num)));
}
private:
static bool is_inited; // = false
static LARGE_INTEGER frequency;
static void init()
{
if(QueryPerformanceFrequency(&frequency) == 0)
throw std::logic_error("QueryPerformanceCounter not supported: " + std::to_string(GetLastError()));
}
};对于Linux来说,这甚至更容易。只需阅读clock_gettime的手册页并修改上面的代码即可。
发布于 2016-12-17 21:56:49
GCC 5.3.0实现
C++ stdlib在GCC内部消息来源:
high_resolution_clock是system_clock的别名system_clock转发给下列可用的第一个:clock_gettime(CLOCK_REALTIME, ...)gettimeofdaytime
steady_clock转发给下列可用的第一个:clock_gettime(CLOCK_MONOTONIC, ...)system_clock
然后,CLOCK_REALTIME对CLOCK_MONOTONIC的解释是:单调?
https://stackoverflow.com/questions/13263277
复制相似问题