我用linux perf來分析我的程序,我無法理解結果。「採樣」在perf輸出中意味着什麼?
10.5% 2 fun .......... | |- 80% - ABC | call_ABC -- 20% - DEF call_DEF
上面的例子是指 '樂' 具有兩個樣品,並有助於10.5%的開銷,
和其中的80%是從ABC稱爲,20%從DEF。我對嗎?
現在我們只有兩個樣本,那麼'perf'如何計算ABC和DEF的分數?
他們爲什麼不是50%?劑量'perf'使用額外信息?
我用linux perf來分析我的程序,我無法理解結果。「採樣」在perf輸出中意味着什麼?
10.5% 2 fun .......... | |- 80% - ABC | call_ABC -- 20% - DEF call_DEF
上面的例子是指 '樂' 具有兩個樣品,並有助於10.5%的開銷,
和其中的80%是從ABC稱爲,20%從DEF。我對嗎?
現在我們只有兩個樣本,那麼'perf'如何計算ABC和DEF的分數?
他們爲什麼不是50%?劑量'perf'使用額外信息?
上面的例子是指 '樂' 具有兩個樣品,並有助於10.5%的開銷,
是的,perf report -g -n
這部分顯示,2 19的樣本(2 19 10.5%)爲在foo函數本身。其他17個樣本採樣。
我剛剛使用最近的gcc(-static -O3 -fno-inline -fno-omit-frame-pointer -g
)和perf(對於低分辨率採樣爲perf record -e cycles:u -c 500000 -g ./test12968422
或對於高分辨率爲-c 5000
)複製了您的代碼。現在perf有點不同的重量規則,但想法應該是一樣的。如果程序只有兩個樣本,並且兩個都在foo
中,call_DEF/_ABC(沒有附加信息)的調用圖(perf report -n -g callee
)爲50。這個方案實際上有foo中運行時的86%,其中61%來自ABC調用時,86 25%,從DEF調用時:
100% 2 fun
- fun
+ 50% call_DEF
+ 50% call_ABC
什麼樣的附加信息PERF可以用來重建的更多信息?我認爲它可以是call_DEF和call_ABC的自重;或者它可以是所有樣本調用堆棧中callchain部分的「call_ABC-> foo」和「call_DEF-> foo」部分的頻率。
從linux內核版本4.4/4.10開始,我無法重現您的情況。我在call_ABC和call_DEF中添加了不同數量的自我工作。他們兩個都只是打電話給foo進行固定的工作量。現在我有19個樣品的-e cycles:u -c 54000 -g
,13 call_ABC,2 call_DEF,2爲了好玩(和2在一些隨機函數):
Children Self Samples Symbol
74% 68% 13 [.] call_ABC
16% 10.5% 2 [.] call_DEF
10.5% 10.5% 2 [.] fun
- fun
+ 5.26% call_ABC
+ 5.26% call_DEF
所以,儘量PERF的新版本,而不是3.2版本的Linux內核時代。
首先fun
唯一的工作來源,從ABC和DEF調用時不相等的股份:在有趣的ABC和DEF不相等的工作,等於小的工作
#define g 100000
int a[2+g];
void fill_a(){
a[0]=0;
for(int f=0;f<g;f++)
a[f+1]=f;
}
int fun(int b)
{
while(a[b])
b=a[b];
return b;
}
int call_ABC(int b)
{
int d = b;
b = fun(d);
return d-b;
}
int call_DEF(int b)
{
int e = b;
b = fun(e);
return e+b;
}
int main()
{
int c,d;
fill_a();
c=call_ABC(100000);
c=call_DEF(45000);
return c+d;
}
第二個來源:
#define g 100000
int a[2+g];
void fill_a(){
a[0]=0;
for(int f=0;f<g;f++)
a[f+1]=f;
}
int fun(int b)
{
while(a[b])
b=a[b];
return b;
}
int call_ABC(int b)
{
int d = b;
while(a[d])
d=a[d];
b = fun(5000);
return d-b;
}
int call_DEF(int b)
{
int e = b;
while(a[e])
e=a[e];
b = fun(5000);
return e+b;
}
int main()
{
int c,d;
fill_a();
c=call_ABC(100000);
c=call_DEF(20000);
return c+d;
}
你能否提供你用來執行perf的語法/選項? – csj