3 回答

TA貢獻(xiàn)2012條經(jīng)驗 獲得超12個贊
如果您的目標(biāo)是使用分析器,請使用其中一個建議器。
但是,如果你很匆忙,并且你可以手動中斷調(diào)試器下的程序,而主觀速度很慢,那么找到性能問題的方法很簡單。
只需暫停幾次,每次都看一下調(diào)用堆棧。如果有一些代碼浪費了一定比例的時間,20%或50%或其他什么,那就是你在每個樣本的行為中捕獲它的概率。所以這大約是您將看到它的樣本的百分比。沒有必要的教育猜測。如果您確實猜到了問題所在,這將證明或反駁它。
您可能會遇到不同大小的多個性能問題。如果你清除其中任何一個,剩下的將占用更大的百分比,并且在隨后的傳球中更容易發(fā)現(xiàn)。當(dāng)在多個問題上復(fù)合時,這種放大效應(yīng)可以導(dǎo)致真正大規(guī)模的加速因子。
警告:程序員往往對這種技術(shù)持懷疑態(tài)度,除非他們自己使用它。他們會說分析器會給你這些信息,但只有當(dāng)他們對整個調(diào)用堆棧進(jìn)行采樣時才會這樣,然后讓你檢查一組隨機(jī)的樣本。(摘要是失去洞察力的地方。)調(diào)用圖不會給你相同的信息,因為
他們沒有在教學(xué)層面總結(jié),并且
它們在遞歸的情況下給出令人困惑的摘要。
他們還會說它只適用于玩具程序,實際上它適用于任何程序,并且它似乎在更大的程序上工作得更好,因為它們往往有更多的問題要找。他們會說它有時會發(fā)現(xiàn)不是問題的東西,但只有在你看到一次之后才會這樣。如果您在多個樣本上發(fā)現(xiàn)問題,那就是真實的。
PS如果有一種方法可以在某個時間點收集線程池的調(diào)用堆棧樣本,那么這也可以在多線程程序上完成,就像在Java中一樣。
PPS作為一個粗略的概括,您在軟件中擁有的抽象層越多,您就越有可能發(fā)現(xiàn)這是性能問題的原因(以及獲得加速的機(jī)會)。
補充:它可能不是很明顯,但堆棧采樣技術(shù)在遞歸的情況下同樣有效。原因是通過刪除指令節(jié)省的時間通過包含它的樣本的分?jǐn)?shù)來近似,而不管樣本中可能出現(xiàn)的次數(shù)。
我經(jīng)常聽到的另一個反對意見是:“ 它會在某個地方隨機(jī)停止,它會錯過真正的問題 ”。這來自對現(xiàn)實問題的先驗概念。性能問題的一個關(guān)鍵屬性是他們無視期望。抽樣告訴你一些問題,你的第一反應(yīng)是難以置信。這很自然,但你可以確定它是否發(fā)現(xiàn)問題是真的,反之亦然。
補充:讓我對其工作原理進(jìn)行貝葉斯解釋。假設(shè)有一些指令I(lǐng)(調(diào)用或其他)在調(diào)用堆棧中占用了一小部分f時間(因此成本太高)。為簡單起見,假設(shè)我們不知道是什么f,但假設(shè)它是0.1,0.2,0.3,...... 0.9,1.0,并且每種可能性的先驗概率為0.1,因此所有這些成本同樣可能先驗。
然后假設(shè)我們只采集2個堆棧樣本,并且我們看到I兩個樣本的指令,指定觀察o=2/2。這給了我們對頻率f的新估計I,根據(jù)這個:
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%,高于之前假設(shè)的60%。
假設(shè)先前的假設(shè)是不同的。假設(shè)我們假設(shè)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
現(xiàn)在它說P(f> = 0.5)是26%,高于先前假設(shè)的0.6%。所以貝葉斯允許我們更新我們對可能成本的估計I。如果數(shù)據(jù)量很小,它并不能準(zhǔn)確地告訴我們成本是多少,只是它足夠大,值得修復(fù)。
另一種看待它的方法叫做繼承規(guī)則。如果你把硬幣翻了兩次,并且兩次都出現(xiàn)了硬幣,那么它對硬幣的可能加權(quán)有什么影響呢?值得尊重的回答方式是說它是Beta分布,平均值(命中數(shù)+ 1)/(嘗試次數(shù)+2)=(2 + 1)/(2 + 2)= 75%。
(關(guān)鍵是我們I
不止一次看到。如果我們只看到一次,除了f
> 0 之外,這并沒有告訴我們多少。)
因此,即使是非常少量的樣本也可以告訴我們很多關(guān)于它看到的指令成本的信息。(而且將看到他們的頻率,平均成比例的成本。如果n
采取試樣,f
是成本,那么I
將出現(xiàn)在nf+/-sqrt(nf(1-f))
樣品。實施例,n=10
,f=0.3
,即3+/-1.4
樣品)。
添加,以直觀地感受測量和隨機(jī)堆棧采樣之間的差異:
現(xiàn)在有一些分析器可以對堆棧進(jìn)行采樣,即使是在掛鐘時間,但是出現(xiàn)的是測量(或熱路徑,或熱點,從中得到)一個“瓶頸”很容易隱藏)。他們沒有告訴你(他們很容易)你自己的實際樣本。如果您的目標(biāo)是找到瓶頸,那么您需要查看的數(shù)量平均為 2除以所需的時間。因此,如果需要30%的時間,平均2 / .3 = 6.7個樣本將顯示它,并且20個樣本顯示它的機(jī)會是99.2%。
以下是檢查測量和檢查堆疊樣本之間差異的袖口圖示。瓶頸可能是這樣的一個大塊,或許多小塊,它沒有任何區(qū)別。
測量是水平的; 它告訴你特定例程所花費的時間。采樣是垂直的。如果有任何方法可以避免整個程序在那一刻所做的事情,如果你在第二個樣本上看到它,你就找到了瓶頸。這就是產(chǎn)生差異的原因 - 看到花費時間的全部原因,而不僅僅是花費多少。

TA貢獻(xiàn)1796條經(jīng)驗 獲得超4個贊
我假設(shè)你正在使用GCC。標(biāo)準(zhǔn)解決方案是使用gprof進(jìn)行分析。
確保-pg
在分析之前添加到編譯中:
cc -o myprog myprog.c utils.c -g -pg
我還沒有嘗試過,但我聽說過google-perftools的好消息。絕對值得一試。
相關(guān)問題在這里。
其他一些流行語如果gprof
不適合你:Valgrind,Intel VTune,Sun DTrace。
- 3 回答
- 0 關(guān)注
- 723 瀏覽
添加回答
舉報