繁体   English   中英

在C ++实现中std :: chrono :: system_clock vs std :: chrono :: steady_clock的精度是多少?

[英]Precision of std::chrono::system_clock vs std::chrono::steady_clock across C++ implementations?

以下程序:

#include <chrono>
#include <iostream>
#include <vector>

inline uint64_t now() {
    return std::chrono::duration_cast
       <std::chrono::nanoseconds> 
       (std::chrono::system_clock::now()
          .time_since_epoch())
       .count();
}

int main() {
        std::vector<uint64_t> v;
        for (int i = 0; i < 1000; i++)
                v.push_back(now());

        for (int i = 0; i < v.size()-1; i++)
                std::cout << v[i+1] - v[i] << std::endl;
}

打印数量在250到300左右的范围内:

g++ (Ubuntu 8.2.0-7ubuntu1) 8.2.0

有:

Linux 4.18.0-15-generic #16-Ubuntu SMP x86_64 x86_64 x86_64 GNU/Linux

意思是std :: chrono :: system_clock在这个系统上是纳秒精度(很可能是gettimeofday对吗?)。 我有几个问题:

  1. 这个系统在std::chrono::system_clock std::chrono::steady_clock std::chrono::system_clockstd::chrono::steady_clock什么? (是的,我知道它们在标准中有不同的指定,我正在考虑这个实现。)

  2. 所有libstdc ++目标的答案是否相同?

  3. 所有libc ++目标的答案是否相同?

  4. Windows / MSVC目标的答案是否相同?

我不确定你是否在问你想要回答的问题。 我看到的一件事是你在稳定性和系统时钟方面的问题,就其精度而言。 第二,从单独的片段判断,是关于system_clock :: now,duration_cast,vector :: push_back / vector :: insert和(implicit)vector :: resize的性能。

如果你不介意,我会尝试回答这两个中的第一个:

  • 这些时钟的关键是一个(system_clock)适合与任何物理日历互操作,因此有时可以返回( 随着夏季/冬季时间的过渡 当有人或某事改变机器上的系统时间时,请参阅std :: system_clock和std :: steady_clock之间的区别? ),另一个(steady_clock)保证只能前进,并且有利于测量push_back的长度。
  • 这些时钟的分辨率无法保证。 这就是为什么你应该保持时钟的持续时间类型,只要合理,并且只在打印之前使用.count()访问器; 但是,由于对所用的时间没有任何保证,你应该也可以
    1. 做一个duration_cast稳定的东西,
    2. 或者执行一些花哨的后缀选择,使用句点作为某些元程序的参数。
  • 没有关于time_since_epoch()的含义的保证,在C ++ 20之前,没有办法比较属于两个不同时钟的time_points / durations
  • 并且,请记住,在任何系统上,对任何时钟的周期分辨率都没有任何保证; 我发现了困难的方法(编写一些花哨的模板),甚至不能保证周期可以被1000整除...对于其中一个时钟,其中一个库使用1超过10 ^ 8作为周期.. 。

因此,询问任何特定的实现并希望它们的常量也将用于其他实现 - 即使对于同一个供应商 - 也是不可取的。 我总是尝试使用clock的:: time_point,或者:: duration,或者作为最后的手段,毫秒或纳秒,这取决于我测量什么以及测量的东西飞得多快。

还请注意有system_clock ::(to / from)_time_t()函数,即使system_clock :: duration具有更精细的周期,它肯定会产生1超过1的值(秒)。

使用steady_clock,其time_point和尽可能晚地调用duration_cast的修订片段将是:

#include <chrono>
#include <iostream>
#include <vector>

int main() {
        using namespace std::chrono;
        using clock = steady_clock;

        std::vector<clock::time_point> v;
        for (int i = 0; i < 1000; i++)
                v.push_back(clock::now());

        for (size_t i = 0; i < v.size()-1; i++) {
                std::cout
                        << duration_cast<nanoseconds>(
                                v[i+1] - v[i]
                                ).count()
                        << "ns\n";
        }
}

编辑:哦,另一件事是原始代码中没有任何内容可以证明你的库在system_clock中使用nano作为句点。 你正在做一个duration_cast <nanoseconds>(如果必须的话,它使用整数除法)并从中获得周期,但持续时间不同,例如duration_cast <duration <long long,pico >>,你也可以在下面的某个地方获得非零值最低的1000.不太可能,但可能永远不会少。

编辑2: Sheesh这复杂。 在第一个项目符号点中更改了system_clock不稳定的原因。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM