簡體   English   中英

我應該如何解釋OProfile輸出?

[英]How am I supposed to interpret OProfile output?

我最近嘗試使用OProfile對應用程序進行性能分析。 收集到的數據對我來說已經非常有價值,但是我很難對其進行准確的解釋。 使用oprofile設置並運行我的應用程序后,我生成了報告並得到:

root @ se7xeon:src#opreport圖片:test -l -t 1
溢出狀態不可用
CPU:具有4個超線程的P4 / Xeon,速度3191.66 MHz(估計)
計數的GLOBAL_POWER_EVENTS事件(不停止處理器的時間),單位掩碼為0x01(強制性),計數為750000
樣品%符號名稱
215522 84.9954 cci :: Image :: interpolate(unsigned char *,cci :: Matrix const&)const
17998 7.0979 cci :: Calc :: diff(unsigned char const *,unsigned char const *)
13171 5.1942 cci :: Image :: getIRect(unsigned char *,int,int)const
5519 2.1765 cci :: Image :: getFRect(unsigned char *,double,double)const

好的,所以我的插值函數負責應用程序84%的執行時間(過長)。 然后似乎可以考慮一下:

root @ se7xeon:src#opannotate圖像:test --source
[...]

/* cci::Image::interpolate(unsigned char*, cci::Matrix<cci::Point2DF> const&) const total: 215522   84.9954 */  
1392  0.5529 :void Image::interpolate(CCIPixel *output, const Matrix<Point2DF> &inputPoints) const throw()  
4  0.0016 :{  
[...]  
:                col0 = static_cast<int>(point[idx].x);  
3  0.0012 :      col1 = col0+1;  
629  0.2498 :    row0 = static_cast<int>(point[idx].y);  
385  0.1529 :    row1 = row0+1;  
56214 22.3266 :  if (col0 < 0 || col1 >= m_width || row0 < 0 || row1 >= m_height)  
:                {  
:                        col0 = row0 = col1 = row1 = 0;  
:                }  

如果我理解正確,則if條件占程序執行時間的22%以上。 開括號和函數聲明似乎要花費時間,是否應該對應於函數調用開銷(“堆棧上的推入參數,跳轉,彈出參數”序列)?

我更改了源代碼中的某些內容(與后來的瓶頸有關,因為我不知道如何優化if),重新編譯,再次通過oprofile運行(不要忘記opcontrol --reset)。 現在,帶注釋的代碼在同一位置看起來像這樣:

6  0.0024 :     curPx = point[idx].x;  
628  0.2477 :   curPy = point[idx].y;  
410  0.1617 :   col0 = static_cast<int>(curPx);  
57910 22.8380 : col1 = col0+1;  
:               row0 = static_cast<int>(curPy);  
:               row1 = row0+1;  
:               if (col0 < 0 || col1 >= m_width || row0 < 0 || row1 >= m_height)  
:               {  
:                   col0 = row0 = col1 = row1 = 0;  
:               }  

這次,if根本不花時間(?),最昂貴的指令是“ col1 = col0 + 1”,整個耗時塊似乎都已向上移動。 怎么會這樣? 可以完全信任此漏洞以查明源中的瓶頸嗎?

我的另一個疑問是,當我設置opcontrol時,我將跟蹤事件輸入為GLOBAL_POWER_EVENTS,樣本數量為750k。 在輸出中,插值函數似乎占了84%,但其中記錄的樣本數量僅略高於200k。 那甚至不是請求數量的50%。 我是否了解剩余的〜500k樣本是由輸出中未列出的應用程序(內核,Xorg等)采集的?

在分析優化的代碼時,您實際上不能依賴准確的源代碼行。 編譯器將內容移動太多。

為了獲得准確的圖像,您將需要查看代碼反匯編程序輸出。

OProfile可以(他們告訴我)在牆上時鍾時間(不是CPU)上獲取堆棧樣本,並且它可以為您提供行級百分比。 您正在尋找的是包含在大部分堆棧樣本中的行。

在手動調整代碼之后,我才會打開編譯器優化,因為它只是隱藏了東西。

當您說插值例程使用84%的時間時,會觸發一個問題。 整個程序需要一些時間,對嗎? 這需要100%的時間。 如果將程序的時間減少一半,或者將其時間增加一倍,則仍將花費100%的時間。 84%的插值是否過多取決於是否進行了過多的操作。

因此,我建議您不要問例程的百分比是否太大。 相反,您會尋找花費大量時間的代碼行,並詢問是否可以對其進行優化。 看到不同? 優化代碼后,它可以大大減少總體運行時間,但仍可能占總運行時間的很大一部分。 當什么都不花很大的錢時,代碼不是最佳的。 當所有花費很大的事情都無法改善時,代碼是最佳的。

我不在乎只給出數字的東西。 我想要的是洞察力。 例如,如果該例程占84%的時間,那么如果您對堆棧進行10個采樣,則該采樣將占8.4個。 確切的數字無關緊要。 重要的是要了解為什么它在那里。 真的真的有必要去很多地方嗎? 這就是查看堆棧樣本可以告訴您的內容。 也許您實際上需要進行兩次內插? 人們通常通過分析原因來發現,他們試圖加速的例程幾乎不需要調用,甚至根本不需要調用。 我猜不到你的情況。 只有檢查程序狀態的洞察力可以告訴您。

暫無
暫無

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

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