亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何分析在Linux上運行的C ++代碼?

如何分析在Linux上運行的C ++代碼?

胡說叔叔 2019-05-20 17:25:24
我有一個在Linux上運行的C ++應用程序,我正在優化它。如何確定代碼的哪些區域運行緩慢?
查看完整描述

3 回答

?
繁花如伊

TA貢獻2012條經驗 獲得超12個贊

如果您的目標是使用分析器,請使用其中一個建議器。


但是,如果你很匆忙,并且你可以手動中斷調試器下的程序,而主觀速度很慢,那么找到性能問題的方法很簡單。


只需暫停幾次,每次都看一下調用堆棧。如果有一些代碼浪費了一定比例的時間,20%或50%或其他什么,那就是你在每個樣本的行為中捕獲它的概率。所以這大約是您將看到它的樣本的百分比。沒有必要的教育猜測。如果您確實猜到了問題所在,這將證明或反駁它。


您可能會遇到不同大小的多個性能問題。如果你清除其中任何一個,剩下的將占用更大的百分比,并且在隨后的傳球中更容易發現。當在多個問題上復合時,這種放大效應可以導致真正大規模的加速因子。


警告:程序員往往對這種技術持懷疑態度,除非他們自己使用它。他們會說分析器會給你這些信息,但只有當他們對整個調用堆棧進行采樣時才會這樣,然后讓你檢查一組隨機的樣本。(摘要是失去洞察力的地方。)調用圖不會給你相同的信息,因為


他們沒有在教學層面總結,并且

它們在遞歸的情況下給出令人困惑的摘要。

他們還會說它只適用于玩具程序,實際上它適用于任何程序,并且它似乎在更大的程序上工作得更好,因為它們往往有更多的問題要找。他們會說它有時會發現不是問題的東西,但只有在你看到一次之后才會這樣。如果您在多個樣本上發現問題,那就是真實的。


PS如果有一種方法可以在某個時間點收集線程池的調用堆棧樣本,那么這也可以在多線程程序上完成,就像在Java中一樣。


PPS作為一個粗略的概括,您在軟件中擁有的抽象層越多,您就越有可能發現這是性能問題的原因(以及獲得加速的機會)。


補充:它可能不是很明顯,但堆棧采樣技術在遞歸的情況下同樣有效。原因是通過刪除指令節省的時間通過包含它的樣本的分數來近似,而不管樣本中可能出現的次數。


我經常聽到的另一個反對意見是:“ 它會在某個地方隨機停止,它會錯過真正的問題 ”。這來自對現實問題的先驗概念。性能問題的一個關鍵屬性是他們無視期望。抽樣告訴你一些問題,你的第一反應是難以置信。這很自然,但你可以確定它是否發現問題是真的,反之亦然。


補充:讓我對其工作原理進行貝葉斯解釋。假設有一些指令I(調用或其他)在調用堆棧中占用了一小部分f時間(因此成本太高)。為簡單起見,假設我們不知道是什么f,但假設它是0.1,0.2,0.3,...... 0.9,1.0,并且每種可能性的先驗概率為0.1,因此所有這些成本同樣可能先驗。


然后假設我們只采集2個堆棧樣本,并且我們看到I兩個樣本的指令,指定觀察o=2/2。這給了我們對頻率f的新估計I,根據這個:


Prior                                    

P(f=x) x  P(o=2/2|f=x) P(o=2/2&&f=x)  P(o=2/2&&f >= x)  P(f >= x | o=2/2)


0.1    1     1             0.1          0.1            0.25974026

0.1    0.9   0.81          0.081        0.181          0.47012987

0.1    0.8   0.64          0.064        0.245          0.636363636

0.1    0.7   0.49          0.049        0.294          0.763636364

0.1    0.6   0.36          0.036        0.33           0.857142857

0.1    0.5   0.25          0.025        0.355          0.922077922

0.1    0.4   0.16          0.016        0.371          0.963636364

0.1    0.3   0.09          0.009        0.38           0.987012987

0.1    0.2   0.04          0.004        0.384          0.997402597

0.1    0.1   0.01          0.001        0.385          1


                  P(o=2/2) 0.385                

最后一欄說,例如,f> = 0.5 的概率為92%,高于之前假設的60%。


假設先前的假設是不同的。假設我們假設P(f = 0.1)是.991(幾乎是確定的),并且所有其他可能性幾乎是不可能的(0.001)。換句話說,我們先前的確定性I是便宜的。然后我們得到:


Prior                                    

P(f=x) x  P(o=2/2|f=x) P(o=2/2&& f=x)  P(o=2/2&&f >= x)  P(f >= x | o=2/2)


0.001  1    1              0.001        0.001          0.072727273

0.001  0.9  0.81           0.00081      0.00181        0.131636364

0.001  0.8  0.64           0.00064      0.00245        0.178181818

0.001  0.7  0.49           0.00049      0.00294        0.213818182

0.001  0.6  0.36           0.00036      0.0033         0.24

0.001  0.5  0.25           0.00025      0.00355        0.258181818

0.001  0.4  0.16           0.00016      0.00371        0.269818182

0.001  0.3  0.09           0.00009      0.0038         0.276363636

0.001  0.2  0.04           0.00004      0.00384        0.279272727

0.991  0.1  0.01           0.00991      0.01375        1


                  P(o=2/2) 0.01375                

現在它說P(f> = 0.5)是26%,高于先前假設的0.6%。所以貝葉斯允許我們更新我們對可能成本的估計I。如果數據量很小,它并不能準確地告訴我們成本是多少,只是它足夠大,值得修復。

另一種看待它的方法叫做繼承規則。如果你把硬幣翻了兩次,并且兩次都出現了硬幣,那么它對硬幣的可能加權有什么影響呢?值得尊重的回答方式是說它是Beta分布,平均值(命中數+ 1)/(嘗試次數+2)=(2 + 1)/(2 + 2)= 75%。

(關鍵是我們I不止一次看到。如果我們只看到一次,除了f> 0 之外,這并沒有告訴我們多少。)

因此,即使是非常少量的樣本也可以告訴我們很多關于它看到的指令成本的信息。(而且將看到他們的頻率,平均成比例的成本。如果n采取試樣,f是成本,那么I將出現在nf+/-sqrt(nf(1-f))樣品。實施例,n=10,f=0.3,即3+/-1.4樣品)。


添加,以直觀地感受測量和隨機堆棧采樣之間的差異:
現在有一些分析器可以對堆棧進行采樣,即使是在掛鐘時間,但是出現的是測量(或熱路徑,或熱點,從中得到)一個“瓶頸”很容易隱藏)。他們沒有告訴你(他們很容易)你自己的實際樣本。如果您的目標是找到瓶頸,那么您需要查看的數量平均為 2除以所需的時間。因此,如果需要30%的時間,平均2 / .3 = 6.7個樣本將顯示它,并且20個樣本顯示它的機會是99.2%。

以下是檢查測量和檢查堆疊樣本之間差異的袖口圖示。瓶頸可能是這樣的一個大塊,或許多小塊,它沒有任何區別。


測量是水平的; 它告訴你特定例程所花費的時間。采樣是垂直的。如果有任何方法可以避免整個程序在那一刻所做的事情,如果你在第二個樣本上看到它,你就找到了瓶頸。這就是產生差異的原因 - 看到花費時間的全部原因,而不僅僅是花費多少。


查看完整回答
反對 回復 2019-05-20
?
一只萌萌小番薯

TA貢獻1795條經驗 獲得超7個贊

您可以使用Valgrind以下選項

valgrind --tool=callgrind ./(Your binary)

它將生成一個名為的文件callgrind.out.x。然后,您可以使用kcachegrind工具來讀取此文件。它會給你一個圖形分析的結果,比如哪條線的成本是多少。


查看完整回答
反對 回復 2019-05-20
?
SMILET

TA貢獻1796條經驗 獲得超4個贊

我假設你正在使用GCC。標準解決方案是使用gprof進行分析。

確保-pg在分析之前添加到編譯中:

cc -o myprog myprog.c utils.c -g -pg

我還沒有嘗試過,但我聽說過google-perftools的消息。絕對值得一試。

相關問題在這里。

其他一些流行語如果gprof不適合你:Valgrind,Intel VTune,Sun DTrace。


查看完整回答
反對 回復 2019-05-20
  • 3 回答
  • 0 關注
  • 752 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號