由于CPU能耗優(yōu)化的原因,火焰圖有時(shí)并不準(zhǔn)確。為此,我們來(lái)做一個(gè)小實(shí)驗(yàn)。
(還不熟悉什么是火焰圖的可以看看文章末尾火焰圖系列文章匯總)
1.小實(shí)驗(yàn)
這是一個(gè)簡(jiǎn)單C程序,其實(shí)就是一個(gè)死循環(huán),如下:
#include
編譯后可執(zhí)行程序名為 func。接下來(lái)我開(kāi)了兩個(gè)終端,分別使用 taskset將 func運(yùn)行在CPU0和CPU1上:
taskset 0x1 ./functaskset 0x2 ./func
然后使用bcc+flamegraph繪制火焰圖:
/bcc/profile -I -F 99 -daf 10 > out.profile/mnt/sdb/FlameGraph/flamegraph.plout.svg
得到的火焰圖:

我的測(cè)試環(huán)境是Qemu/KVM, 32核。
我們可以看到,火焰圖顯示, func程序占用了近四分之一的CPU時(shí)間。但是由于我們把 func綁定在CPU0和1上執(zhí)行,根據(jù)小學(xué)數(shù)學(xué)我們應(yīng)該可以計(jì)算出來(lái) func最多占用 2/32=6.25%的時(shí)間。
是不是有點(diǎn)不對(duì)?
2.原因
由于Linux會(huì)對(duì)CPU進(jìn)行能耗優(yōu)化,在低負(fù)載的時(shí)候,CPU并不是滿負(fù)荷工作(降頻),因此對(duì)于Idle的CPU,bcc的采樣數(shù)會(huì)減少,從而導(dǎo)致總采樣數(shù)減少。我們可以看到,我們的采樣頻率是99個(gè)樣本/(min*CPU)。運(yùn)行了10s,那么總的樣本數(shù)應(yīng)該大約為 99*10*32=31680。而實(shí)際的總采樣數(shù)只有8197。分母小了,自然 func占用的CPU時(shí)間比例增加了。
3.解決辦法
當(dāng)然,我們可以修改CPUfreq強(qiáng)制讓所有滿負(fù)荷工作。但是這樣一來(lái)麻煩,二來(lái)我的測(cè)試環(huán)境是虛擬機(jī),修改起來(lái)更加麻煩。我們希望用一個(gè)簡(jiǎn)單的方法解決。
這就要提到flamegraph的隱藏功能了。為什么叫隱藏功能?因?yàn)槿绻愫?jiǎn)單地 ./flamegraph.pl--help他不會(huì)告訴你這個(gè)用法。但是實(shí)際上他已經(jīng)實(shí)現(xiàn)了這個(gè)功能,語(yǔ)法是:
./flamegraph.pl --total=N < out.profile > out2.svg
其中N為用戶規(guī)定的總采樣數(shù)。在我們的示例中,應(yīng)該是31680。這樣,我們繪制出來(lái)的火焰圖是這個(gè)樣子的:

嗯,的確有點(diǎn)丑,但是6.26%才是 func真正消耗了的CPU時(shí)間比例。
4.關(guān)于CPU時(shí)間準(zhǔn)確性的討論
怎樣才算是繪制了準(zhǔn)確的火焰圖呢?
考慮如下情形,如果CPU1滿負(fù)荷運(yùn)轉(zhuǎn)執(zhí)行 func110秒鐘,而CPU2半負(fù)荷運(yùn)轉(zhuǎn)執(zhí)行 func25秒鐘,剩下5s是idle。
算法1::實(shí)際上 func1和 func2一起是占用了15s的CPU時(shí)間。根據(jù)計(jì)算, func占用的時(shí)間占總時(shí)間的 15s/(10s*32)=4.69%。
算法2:如果按照上面第三節(jié)所描述的方法繪制火焰圖,采樣結(jié)果應(yīng)該是 func1有大約990個(gè)樣本, func2有大約 990/2/2=248個(gè)樣本,繪制出來(lái)的火焰圖 func占比為 (990+248)/31680=3.9%
兩者不相等!筆者認(rèn)為,原因在于二者算法所獲結(jié)果的含義不同。算法1計(jì)算出來(lái)的是在這種運(yùn)行情形下實(shí)際 func的執(zhí)行時(shí)間占比。而算法2計(jì)算出來(lái)(或者說(shuō)繪制出來(lái))的是在CPU滿負(fù)荷運(yùn)轉(zhuǎn)下func的CPU時(shí)間占比。從現(xiàn)實(shí)來(lái)看,不同背景負(fù)載,不同情形下同一個(gè)workload的運(yùn)行時(shí)間可能不同。當(dāng)系統(tǒng)負(fù)載加重時(shí),Linux會(huì)自動(dòng)控制CPUfreq將CPU頻率增加。單單查看在某一個(gè)情形下workload的CPU執(zhí)行時(shí)間意義有限。但是,對(duì)于一個(gè)workload而言,他所需要占用的計(jì)算資源量往往是相同的。因此,從程序優(yōu)化角度而言,采用第三節(jié)所描述的方法計(jì)算CPU滿負(fù)載下應(yīng)用程序的時(shí)間占比對(duì)于我們優(yōu)化代碼更具有指導(dǎo)性意義。
-
cpu
+關(guān)注
關(guān)注
68文章
11335瀏覽量
226005 -
程序
+關(guān)注
關(guān)注
117文章
3849瀏覽量
85501
原文標(biāo)題:火焰圖系列之使用火焰圖隱藏功能提高繪制精度
文章出處:【微信號(hào):LinuxDev,微信公眾號(hào):Linux閱碼場(chǎng)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
昉·星光開(kāi)發(fā)板火焰傳感器探測(cè)火光
火焰傳感器的特征及應(yīng)用
honeywell火焰探測(cè)器
火焰探測(cè)器參考方案
基于單片機(jī)的防火報(bào)警系統(tǒng)_DS18B20測(cè)溫+火焰傳感器 相關(guān)資料下載
為巡線小車添加火焰檢測(cè)功能
Arduion UNO&Nano;火焰傳感器模塊
隧道專用火焰探測(cè)器的技術(shù)參數(shù)
火焰圖:全局視野的Linux性能剖析
使用Arthas火焰圖工具的Java應(yīng)用性能分析和優(yōu)化經(jīng)驗(yàn)
火焰圖系列之使用火焰圖隱藏功能提高繪制精度
評(píng)論