简体   繁体   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?

The following program: 以下程序:

#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;
}

prints numbers in the range of about 250 to 300 on: 打印数量在250到300左右的范围内:

g++ (Ubuntu 8.2.0-7ubuntu1) 8.2.0

with: 有:

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

Meaning std::chrono::system_clock is nanosecond precision on this system (most likely gettimeofday right?). 意思是std :: chrono :: system_clock在这个系统上是纳秒精度(很可能是gettimeofday对吗?)。 I have several questions: 我有几个问题:

  1. Whats the difference on this system between std::chrono::system_clock and std::chrono::steady_clock ? 这个系统在std::chrono::system_clock std::chrono::steady_clock std::chrono::system_clockstd::chrono::steady_clock什么? (Yes, I know they are specified differently in the standard, I am taking about this implementation.) (是的,我知道它们在标准中有不同的指定,我正在考虑这个实现。)

  2. Is the answer the same across all libstdc++ targets? 所有libstdc ++目标的答案是否相同?

  3. Is the answer the same across all libc++ targets? 所有libc ++目标的答案是否相同?

  4. Is the answer the same on Windows/MSVC targets? Windows / MSVC目标的答案是否相同?

I'm not sure you are asking the questions you want answered. 我不确定你是否在问你想要回答的问题。 One thing I see is you asking about difference between steady and system clocks, in terms of their precision. 我看到的一件事是你在稳定性和系统时钟方面的问题,就其精度而言。 The second, judging from the snippet alone, is about the performance of the system_clock::now, duration_cast, vector::push_back/vector::insert and (implicit) vector::resize. 第二,从单独的片段判断,是关于system_clock :: now,duration_cast,vector :: push_back / vector :: insert和(implicit)vector :: resize的性能。

I'll try to answer the first of those two, if you don't mind: 如果你不介意,我会尝试回答这两个中的第一个:

  • the crux of those clocks is that one (system_clock) is good for interop with any physical calendar and therefore can sometimes go back ( 这些时钟的关键是一个(system_clock)适合与任何物理日历互操作,因此有时可以返回( with the summer/winter time transition 随着夏季/冬季时间的过渡 when someone or something changes the system time on the machine, see Difference between std::system_clock and std::steady_clock? 当有人或某事改变机器上的系统时间时,请参阅std :: system_clock和std :: steady_clock之间的区别? ), while the other (steady_clock) is guaranteed to only go forward and is good for eg measuring how long push_back is. ),另一个(steady_clock)保证只能前进,并且有利于测量push_back的长度。
  • there are no guarantees about the resolution of those clocks. 这些时钟的分辨率无法保证。 That's why you should keep the clock's duration type as long as reasonable and only use .count() accessor just before printing; 这就是为什么你应该保持时钟的持续时间类型,只要合理,并且只在打印之前使用.count()访问器; but, since there are NO guarantees about the period used, you should probably either 但是,由于对所用的时间没有任何保证,你应该也可以
    1. do a duration_cast to something stable, 做一个duration_cast稳定的东西,
    2. or perform some fancy suffix selection, using the periods as arguments to some metaprograms. 或者执行一些花哨的后缀选择,使用句点作为某些元程序的参数。
  • there are no guarantees about the meaning of time_since_epoch() and prior to C++20 there is no way of comparing time_points/durations belonging to two different clocks 没有关于time_since_epoch()的含义的保证,在C ++ 20之前,没有办法比较属于两个不同时钟的time_points / durations
  • and, please remember, there are NO guarantees about the resolution of the period for any clock, on any system; 并且,请记住,在任何系统上,对任何时钟的周期分辨率都没有任何保证; I found out the hard way (writing some fancy templates), that there is even no guarantee the period will be divisible by 1000... For one of the clocks, one of the libraries used 1 over 10^8 as the period... 我发现了困难的方法(编写一些花哨的模板),甚至不能保证周期可以被1000整除...对于其中一个时钟,其中一个库使用1超过10 ^ 8作为周期.. 。

So, asking about any particular implementation and hoping their constants will be also used in other implementations -- even for the same vendor -- is not advisable. 因此,询问任何特定的实现并希望它们的常量也将用于其他实现 - 即使对于同一个供应商 - 也是不可取的。 I'd always try to either use clock's::time_point, or its ::duration, or, as a last resort, milliseconds or nanoseconds, depending on what do I measure and how fast the measured thingines can fly. 我总是尝试使用clock的:: time_point,或者:: duration,或者作为最后的手段,毫秒或纳秒,这取决于我测量什么以及测量的东西飞得多快。

And also please note there are system_clock::(to/from)_time_t() functions, which definitely will produce a 1 over 1 value (seconds), even if the system_clock::duration has a finer period. 还请注意有system_clock ::(to / from)_time_t()函数,即使system_clock :: duration具有更精细的周期,它肯定会产生1超过1的值(秒)。

The revised snippet, using steady_clock, its time_point and calling duration_cast as late as possible would be: 使用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";
        }
}

Edit: Oh, and another thing is there is nothing in the original code that would prove your library uses nano as a period in the system_clock. 编辑:哦,另一件事是原始代码中没有任何内容可以证明你的库在system_clock中使用nano作为句点。 You are doing a duration_cast<nanoseconds> (which uses integer division if it must) and getting the period from that, but with different duration, something like duration_cast<duration<long long, pico>>, you could also get the nonzero somewhere below the lowest 1000. Not likely, but possible never the less. 你正在做一个duration_cast <nanoseconds>(如果必须的话,它使用整数除法)并从中获得周期,但持续时间不同,例如duration_cast <duration <long long,pico >>,你也可以在下面的某个地方获得非零值最低的1000.不太可能,但可能永远不会少。

Edit 2: Sheesh this is complicated. 编辑2: Sheesh这复杂。 Changed the reason for system_clock being unsteady in the first bullet point. 在第一个项目符号点中更改了system_clock不稳定的原因。

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

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