簡體   English   中英

c ++中的clock()與繁重的CPU負載一致

[英]Is clock() in c++ consistent with heavy CPU loads

現在我基本上有一個程序,它使用時鍾來測試我的程序執行某些操作所需的時間,通常它精確到幾毫秒。 我的問題是:如果CPU負載很重,我仍會得到相同的結果嗎?

時鍾只計算在CPU處理我的進程時嗎?

讓我們假設:多核CPU,但一個不利用多線程的進程

除了同意表明時間取決於許多因素的響應之外,我想提請你注意自C ++ 11以來可用的std::chrono庫:

#include <chrono>
#include <iostream>

int main() {
      auto beg = std::chrono::high_resolution_clock::now();
      std::cout << "*** Displaying Some Stuff ***" << std::endl;
      auto end = std::chrono::high_resolution_clock::now();
      auto dur = std::chrono::duration_cast<std::chrono::microseconds>(end - beg);
      std::cout << "Elapsed: " << dur.count() << " microseconds" << std::endl;
    }

按照標准,該程序將使用系統提供的最高精度時鍾,並以微秒分辨率打勾(還有其他可用的分辨率; 請參閱文檔 )。

樣品運行:

$ g++ example.cpp -std=c++14 -Wall -Wextra -O3
$ ./a.out
*** Displaying Some Stuff ***
Elapsed: 29 microseconds

雖然它比依賴C風格的std::clock()更加冗長,但我覺得它能給你更多的表現力,你可以隱藏一個漂亮的界面背后的冗長(例如, 看看我之前的帖子的答案)我在哪里使用std::chrono來構建一個函數計時器)。

clock的功能取決於OS。 在Windows中,從遠距離的決定, clock給出了大多數其他操作系統(當然是Linux,MacOS和其他與Unix相關的操作系統)的經過時間。

根據您實際想要實現的目標,可能需要測量經過的時間或CPU時間。

在運行其他進程的系統中,經過時間和CPU使用之間的差異可能很大(當然,如果您的CPU不忙於運行應用程序,例如等待網絡數據包通過線路或文件數據從硬盤),然后經過的時間是“avialable”為其他應用程序。

當在同一系統中運行其他進程時,還存在大量錯誤因素/干擾因素:

  • 如果我們假設您的操作系統支持clock作為CPU時間的度量,那么這里的精度並不總是那么好 - 例如,它可能會根據CPU計時器滴答來計算,並且您的進程可能無法運行“如果它正在進行I / O,則完全打勾。

  • 其他進程可以使用“你的”cpu進行中斷處理的部分,在操作系統切換到“將此作為中斷時間計算”之前,當通過網絡處理數據包或硬盤i / o一段時間之后[通常不是很大,但在一個非常繁忙的系統中,它可能占總時間的百分之幾],如果其他進程在“你的”cpu上運行,那么用“你的”進程重新加載緩存的時間到了加載其他進程后的數據,其數據將記入“您的時間”。 這種“干擾”可能會很好地影響您的測量 - 多少取決於系統中“還有什么”。

  • 如果您的進程[通過共享內存]與另一個進程共享數據,那么(在一些情況下,通常是一小部分,但在極端情況下,它可能很重要)會花費一些時間來處理您之間的“緩存 - 窺探請求”進程和其他進程,當您的進程無法執行時。

  • 如果操作系統正在切換任務,那么在您的過程中將花費一半的時間用於切換到您的任務,而在另一個過程中將一半用於切換/切換。 同樣,這通常很小,但如果你有一個非常繁忙的系統,有很多過程開關,它可以加起來。

  • 某些處理器類型,例如Intel的HyperThreading也與您的實際核心共享資源,因此只有部分時間在該核心上花費在您的流程中,並且您的流程的緩存內容現在與其他流程的數據和指令共享 - 意味着您的進程可能會被運行在同一CPU核心上的另一個線程從緩存中“逐出”。

  • 同樣,多核CPU通常具有共享L3緩存,該緩存會受到CPU其他核心上運行的其他進程的影響。

  • 文件緩存和其他“系統緩存”也會受到其他進程的影響 - 因此,如果您的進程正在讀取某些文件,而其他進程也訪問文件,則緩存內容將“少於您自己”。如果系統不那么忙。

為了准確測量您的進程使用系統資源的數量,您需要處理器性能計數器(以及可重現的測試用例,因為您可能需要多次運行相同的設置以確保您獲得“正確”的性能組合計數器)。 當然,大多數這些計數器都是系統范圍的,並且某些類型的處理(例如中斷和其他隨機干擾)會影響測量,因此如果您沒有其他許多(繁忙)進程,那么最准確的結果將是在系統中運行。

當然,在許多情況下,僅測量應用程序的總體時間就足夠了。 同樣,只要您有一個可重現的測試用例,每次在特定場景中運行時都會給出相同(或至少相似)的時間。

每個應用程序都不同,每個系統都不同。 性能測量是一個巨大的主題,並且很難涵蓋所有內容 - 當然,我們不是在這里回答非常具體的問題,“我如何在那里獲得我的PI小百萬分之一小數是在同一系統中運行的其他進程“或者它可能是什么。

CPU中有共享組件,如最后一級緩存,執行單元(在一個內核中的硬件線程之間),因此在負載很重的情況下,您將獲得抖動,因為即使您的應用程序執行了完全相同數量的指令,每條指令也可能需要更多周期(等待內存,因為數據是從緩存,可用執行單元中逐出的),更多周期意味着更多的執行時間(假設Turbo Boost不會補償)。

如果您尋求精確的儀器,請查看硬件計數器

考慮諸如物理CPU上可用的內核數量,超線程和其他BIOS設置(如Intel CPU上的Turbo Boost)以及在查看CPU密集型任務的時序度量時進行編碼時使用的線程技術等因素也很重要。

OpenMP這樣的並行化工具提供了用於計算計算和omp_get_wtime( );時間的內置函數,如omp_get_wtime( ); 在使用這種類型的並行化的程序中,它通常比clock()更准確。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM