Vin*_*ent 85 c++ timer c++11 c++-chrono
std::system_clock和之间有什么区别std::steady_clock?(说明不同结果/行为的示例案例会很棒).
如果我的目标是精确测量的功能(如基准)的执行时间,这将是之间是最好的选择std::system_clock,std::steady_clock和std::high_resolution_clock?
Bil*_*eal 67
从N3376:
20.11.7.1 [time.clock.system]/1:
类的对象
system_clock表示来自系统范围实时时钟的挂钟时间.
20.11.7.2 [time.clock.steady]/1:
类的对象
steady_clock表示time_point随着物理时间的推移而永不减少的值的时钟,以及time_point相对于实时的稳定速率的提前值.也就是说,可能无法调整时钟.
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表示时钟类型.t1并且t2是返回C1::now()调用t1之前返回的值返回的值,以及之前t2发生的这两个调用C1::time_point::max().[注:这意味着C1没有环绕之间t1和t2. - 尾注]表达式:
C1::is_steady
返回:const bool
操作语义:trueift1 <= t2始终为true,时钟滴答之间的时间是常量,否则false.
这就是他们的差异所有标准.
如果您想进行基准测试,最好的选择可能是std::high_resolution_clock,因为您的平台可能会使用高分辨率计时器(例如QueryPerformanceCounter在Windows上)来获得此时钟.但是,如果您正在进行基准测试,则应该考虑使用特定于平台的计时器作为基准测试,因为不同的平台会以不同的方式处理这种情况 例如,某些平台可能会为您提供一些方法来确定程序所需的实际时钟周期数(与在同一CPU上运行的其他进程无关).更好的是,让你的手掌握一个真实的探查器并使用它.
Mat*_*usz 46
Billy根据我完全赞同的ISO C++标准提供了很好的答案.然而,故事的另一面 - 现实生活.现在看来,在流行编译器的实现中,这些时钟之间确实没有区别:
gcc 4.8:
#ifdef _GLIBCXX_USE_CLOCK_MONOTONIC
...
#else
typedef system_clock steady_clock;
#endif
typedef system_clock high_resolution_clock;
Run Code Online (Sandbox Code Playgroud)
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;
Run Code Online (Sandbox Code Playgroud)
在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()));
}
};
Run Code Online (Sandbox Code Playgroud)
对于Linux来说,它更容易.只需阅读手册页clock_gettime并修改上面的代码即可.
Cir*_*四事件 16
GCC 5.3.0实施
C++ stdlib在GCC源代码中:
high_resolution_clock 是别名 system_clocksystem_clock 转发到以下第一个可用的:
clock_gettime(CLOCK_REALTIME, ...)gettimeofdaytimesteady_clock 转发到以下第一个可用的:
clock_gettime(CLOCK_MONOTONIC, ...)system_clock然后CLOCK_REALTIMEvs CLOCK_MONOTONIC解释:CLOCK_REALTIME和CLOCK_MONOTONIC之间的区别?
小智 7
Howard Hinnant 的有关 chrono 的相关讨论,作者chrono:
不要使用high_resolution_clock,因为它是其中之一的别名:
system_clock:它就像一个普通的时钟,用它来处理时间/日期相关的东西steady_clock:它就像一个秒表,用它来计时。小智 6
也许,最显着的区别是,起点std::chrono:system_clock是 1.1.1970,即所谓的 UNIX 纪元。另一方面,通常用于std::chrono::steady_clock计算机的启动时间,它最适合测量间隔。
| 归档时间: |
|
| 查看次数: |
40743 次 |
| 最近记录: |