2017-10-04 57 views
0

我一直在閱讀關於這一點,並且數字沒有加起來。在我的操作系統(Windows),我可以檢查系統時鐘的分辨率是這樣的:std :: chrono似乎沒有給出準確的時鐘分辨率/頻率

LARGE_INTEGER largeInt; // Basically a struct/union containing a long long 
QueryPerformanceFrequency(&largeInt); 
// largeInt now holds the frequency of my system's clock, it's 3903987 
// This ends up being a resolution of about 256 nanoseconds 

所有這些都是好的,但現在我想使用std ::時辰檢查相同的細節。根據cppreference.com和本網站的一個流行答案,std :: chrono時鐘的週期是一個編譯時間比率,由分子和分母組成,它指定了tick之間的秒數。

cppreference.com:

週期:表示蜱週期(每 蜱iethe秒數)

而且從堆棧溢出回答一個 的std ::比

最小可表示持續時間爲 high_resolution_clock :: period :: num/ high_resolution_clock :: period :: den秒。你可以像這樣 打印:

std::cout << 
(double)std::chrono::high_resolution_clock::period::num/ 
std::chrono::high_resolution_clock::period::den; 

所以,我想:

// On Windows the result is typedeffed as intmax_t, which is a typedef for a long long 
    intmax_t numerator = std::chrono::high_resolution_clock::period::num; 
    intmax_t denominator = std::chrono::high_resolution_clock::period::den; 
    // numerator is 1 and denominator is one billion, which would suggest a 
    // tick period of one nanosecond? 

根據什麼解釋了我的系統的時鐘能夠在一個納秒的分辨率?操作系統似乎並不這麼認爲。我也嘗試了一些支持我的系統時鐘頻率在3903987左右的其他工具,所以我不明白它如何管理比這更好的分辨率。

雖然high_resolution_clock :: is_steady結果爲true,但我不確定頻率是否隨CPU功率設置/升壓模式變化而變化。我重新啓動計算機兩次,得到3903994和3903991的頻率計數器,所以每次啓動這個數字似乎都會改變。我想這在編譯時計算時鐘並不理想,而不是開始運行程序。

那麼有什麼方法可以用std :: chrono獲得系統時鐘的實際分辨率/頻率?

+0

這似乎是您必須在處理器製造商手冊中閱讀的內容,而不是通過軟件測試才能達到合理的準確度。現代處理器也一直在改變它們的頻率,所以它的價值也是如此。 – nwp

+0

@nwp所以沒有可靠一致的時鐘這樣的事情?我知道處理器以不同的速度運行,但就計時系統而言,硬件之間沒有標準給出相同的結果? – Zebrafish

+0

時鐘是令人驚訝的複雜的野獸。您可以以某種精度獲取當前時間,但結果會立即出錯。你究竟想實現什麼?微基準? – nwp

回答

0

period::numperiod::den只是告訴你哪個單位的HPC中。

在您的系統,它的單位是納秒。 「tick」不是時鐘增加的單位,而是時鐘單位的時間是,測量的是英寸。

它不測量「處理器週期」,它測量的是納秒。它的工作是相對一致地給你當前的時間,以毫微秒爲單位。

現在,如果CPU每隔256納秒運行一個週期,那麼兩個調用high_resolution_clock::now()以及另一個調用不會小於相隔(因爲它們需要多個週期!)。

C++不公開CPU的時鐘時間。這並非全部有用。

如果您想記錄兩個時間點,請使用clock::now()作爲您的時鐘。如果您想要最佳分辨率,std庫可以取消,請使用high_performance_clock。如果具有100%保證的時鐘時間從不從不倒退,請使用steady_clock(在檢查其分辨率是否足夠後)。

您可以將這些時間點轉換爲系統時鐘,如果您想要日曆時間,則可以將時間點轉換爲time_t。 (時鐘之間的轉換需要您有一個共同的時間點,根據我的經驗;您應該生成一次這個公共時間點並重新使用它)

如果您需要更多的分辨率而不是系統時鐘許可,可以將時間點轉換爲系統時鐘,即time_t,返回到系統時鐘並返回到您的時鐘,減去差值,並以納秒爲單位顯示該差異。

Here是一個SO的答案,做了一堆這些東西。

chrono提供的主要功能是使用不同的時鐘系統進行工作,使其易於使用和安全。它有持續時間和時間點,每個持有他們的單位與他們,因此意外添加秒 - 幾納秒不會發生。