bon*_*gya 5 profile sample perf
我使用 linux perf 来分析我的程序,但我无法理解结果。
10.5% 2 乐趣 .....................
|
|- 80% - ABC
| call_ABC
-- 20% - 防御
调用_DEF
上面的例子意味着 'fun' 有两个样本并且贡献了 10.5% 的开销,
其中80%来自ABC,20%来自DEF。我对吗?
现在我们只有两个样本,那么'perf'如何计算ABC和DEF的分数?
为什么不是 50%?剂量'perf'使用附加信息?
上面的例子意味着“fun”有两个样本并且贡献了10.5%的开销,
是的,这部分perf report -g -n显示 19 个样本中有 2 个(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 的权重规则有点不同,但想法应该是相同的。当程序只有 2 个样本并且两者都在 中时,对于每个 call_DEF/_ABC,foo调用图 ( ) 为 50(无附加信息)。perf report -n -g callee该程序实际上有 86% 的运行时间在 foo 中,其中从 ABC 调用时占 61%,从 DEF 调用时占 86% 的 25%:
100% 2 fun
- fun
+ 50% call_DEF
+ 50% call_ABC
Run Code Online (Sandbox Code Playgroud)
perf 可以使用哪些类型的附加信息来重建更多信息?我认为可以是call_DEF和call_ABC的自重;或者它可以是所有示例调用堆栈中调用链的“call_ABC->foo”和“call_DEF->foo”部分的频率。
使用 Linux 内核版本 4.4 / 4.10 的 perf 我无法重现您的情况。我在 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
Run Code Online (Sandbox Code Playgroud)
因此,请尝试较新版本的 perf,而不是 3.2 Linux 内核时代的版本。
唯一工作的第一个来源fun,从 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;
}
Run Code Online (Sandbox Code Playgroud)
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;
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;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
256 次 |
| 最近记录: |