簡體   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