std :: system_clock和std :: steady_clock之间的区别?
std::system_clock
和std::steady_clock
什么std::steady_clock
? (举例说明不同的结果/行为的例子会很好)。
如果我的目标是精确测量函数的执行时间(比如基准testing), std::system_clock
, std::steady_clock
和std::high_resolution_clock
std::steady_clock
之间的最佳select是什么?
从N3376:
20.11.7.1 [time.clock.system] / 1:
system_clock
类的对象表示来自全系统实时时钟的挂钟时间。
20.11.7.2 [time.clock.steady] / 1:
类
steady_clock
对象表示时间点的值不会随着物理时间的增加而减小,并且时间点的值相对于实时以稳定的速率前进。 也就是说,时钟可能不会被调整。
20.11.7.3 [time.clock.hires] / 1:
high_resolution_clock
类的对象表示具有最短滴答周期的时钟。high_resolution_clock
可能是system_clock
或steady_clock
的同义词。
例如,系统时钟可能受夏时制等因素影响,此时在某一时刻列出的实际时间实际上可能是过去的时间。 (例如在美国,下降时间往后退一个小时,所以同一小时经历“两次”),但是steady_clock
不允许受到这种事情的影响。
在这种情况下,考虑“稳定”的另一种方法是在20.11.3 [time.clock.req] / 2表中定义的要求:
在表59中,
C1
和C2
表示时钟types。t1
和t2
是C1::now()
返回的值,其中返回t1
的调用发生在返回t2
的调用之前,并且这两个调用发生在C1::time_point::max()
。 [注意:这意味着C1
在t1
和t2
之间没有换行。 – 注意]expression式:
C1::is_steady
返回:const bool
操作语义:如果t1 <= t2
始终为真,且时钟滴答之间的时间为常量,则为false
,否则为false
。
这是所有标准都有其差异。
如果你想做基准testing,最好的办法可能是std::high_resolution_clock
,因为你的平台可能使用高分辨率的定时器(例如Windows上的QueryPerformanceCounter
)。 (编辑:从Visual Studio 2013的MSVC ++,还没有使用QueryPerformanceCounter
这个时钟:()但是,如果你是基准testing,你应该真的考虑使用特定于平台的计时器为您的基准,因为不同的平台处理这个不同。实例中,一些平台可能会给你一些确定程序所需的实际时钟滴答数量的方法(独立于在同一CPU上运行的其他进程),更好的办法是使用一个真正的分析器。
比利根据ISO C ++标准提供了一个很好的答案,我完全同意。 然而,故事的另一面 – 现实生活。 现在看来,在实现stream行编译器的时钟之间真的没有什么区别:
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似乎在这里作弊:-)
如果您需要高精度时钟,我build议现在编写符合C ++ 11官方时钟接口的自己的时钟,并等待实现赶上。 这将比直接在你的代码中使用特定于操作系统的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
的手册页,并修改上面的代码。
GCC 5.3.0 (C ++ stdlib在GCC源代码中):
-
high_resolution_clock
是system_clock
的别名 -
system_clock
转发到以下可用的第一个:-
clock_gettime(CLOCK_REALTIME, ...)
-
gettimeofday
-
time
-
-
steady_clock
转发到以下可用的第一个:-
clock_gettime(CLOCK_MONOTONIC, ...)
-
system_clock
-
然后CLOCK_REALTIME
和CLOCK_MONOTONIC
的解释如下: CLOCK_REALTIME和CLOCK_MONOTONIC之间的区别?