2008-11-01 57 views
5

如何計算C++中的操作?我希望以更好的方式分析代碼,而不僅僅是計時,因爲時間通常取整爲0毫秒。如何計算C++中的操作?

+0

指定你是什麼「的意思計數操作「。有些工具可以像分析器一樣分析代碼中的函數調用,但是您也可以看到,添加相應的開關和生成的彙編代碼。 – 2008-11-01 08:54:20

回答

3

可以通過讀取CPU,它是由一個在每個CPU時鐘遞增的時間戳計數器(TSC)做精確的測量。

不幸的是,讀取操作會在代碼中內嵌一些彙編指令。取決於底層架構,讀取成本在〜11(AMD)和〜33(Intel)tsc之間變化。使用1 Ghz CPU,您幾乎可以達到納秒級精度。

爲了執行的代碼可以一個部分的可靠和非侵入性的測量:通過禁用的CPU功能如AMD cool'n

  • 防止CPU縮放頻率相當或英特爾SpeedStep
  • 多次重複測試,收集數組中的度量值,然後將數據保存到文件以進行離線分析。
  • 爲被測試過程選擇實時調度策略,如SHED_RRSHED_FIFO。實時策略減少被測試進程和其他正常進程/內核線程之間的上下文切換次數,這些進程被阻止。
  • 通過mlockall()系統調用來鎖定RAM中所有進程的虛擬地址空間。

Here你可以找到一個準便攜的C++類,我寫的Linux,從Linux內核導出,旨在讀取TSC的架構是i386,x86_64的和IA64。

7

如果你是計時代碼,它是值得在循環中運行很多次,以避免計時器分辨率的影響。所以你可以運行你計時10,000次的東西,並測量運行所有迭代所花費的時間。它可能只需要幾秒鐘的運行,你會得到更好的時間數據。

+1

唯一的困難就是基準會徹底加熱'緩存',而代碼通常在冷藏緩存上運行。但是測量低溫緩存性能很困難。 – 2008-11-01 16:21:41

+0

是的,除非您正在測量緩存本身的性能,否則您需要禁用緩存以進行正確的性能測試。 – 2008-11-02 01:02:01

5

在考慮性能時,使用「操作次數」是一個壞主意。它沒有考慮到每個操作的最佳/最差情況循環計數,緩存缺失,流水線丟失,潛在(自動)並行化等的成本之間的差異。

正如Greg所說,通常它是更好的一個微基準標記的想法就是運行相同的代碼足夠多的時間來獲得相當的時間。

更妙的是與實際工作量運行你的整個應用程序和衡量你真正感興趣的指標,但是這是一個不同的問題...

什麼當然是有用的是制定出你的代碼的複雜度爲複雜度爲 - 知道何時方法將是O(1),O(log n),O(n)等。這通常不涉及知道C++中單個指令的細節 - 雖然你需要知道任何你調用的複雜性。 (Joel的故事Shlemiel the Painter and strlen就是最明顯的例子。)

0

使用更高分辨率的定時器。

3

生成程序集和計數操作。然後查看處理器使用的週期/操作。 然後記得你正在開發一個先發制人的操作系統,並且沒有一個是有效的。

更嚴重的是,擡起你的n並將你的程序縮放到淫穢尺寸。這會讓你知道你的程序速度是多少。

2

如果您希望實際操作數量來自您的硬件,那麼您可能需要考慮安裝像PAPI這樣的軟件包 - 性能API--它可以在許多不同的操作系統和處理器組合中使用。它使用實際的硬件計數器並報告直接或派生值,以獲得許多不同的性能指標,例如Total Ops,FLOPS,緩存命中/未命中等等。它還可以訪問更高分辨率的定時器。

這不是最簡單的軟件包,但報告級別確實可以幫助您分析應用程序在硬件上的行爲。

3

在Linux上使用valgrind。它具有指令級時序,包括緩存分析。

0

爲什麼不只是在探查器下運行你的代碼?這通常會爲您提供關於在函數中花費多少時間以及調用多少次的數據。

知道函數被調用的次數是有用的,因爲如果函數被調用的次數遠遠超過您的感覺,它可以讓您發現潛在的性能問題。

當然,使用探查器會使代碼變慢,但在添加任何類型的儀器時這是不可避免的。

0

如果你想在不使用分析器的情況下精確計時(在windows上),你可以看看this thread,它提供了不同的分析C++代碼的方法。