我们正在使用perf top
来显示CPU使用情况。结果显示了两个函数
samples pcnt function
------ ---- ---------
... ... ....
12617.00 6.8% func_outside
8691.00 4.7% func_inside
.....
实际上,这两个函数是这样嵌套的,并且始终是1对1嵌套。
func_outside() {
....
func_inside()
...
}
我是否应该在perf top
结果中得出结论,4.7%实际上已经包含在6.8%中。如果排除func_inside的成本,func_outside的成本为2.1%(6.8-4.7)?
答案 0 :(得分:1)
报告的每个百分比都不是仅针对该特定功能。因此,func_inside
func_outside
个样本
perf
的工作方式是定期收集性能样本。默认情况下,perf top
只检查当前正在运行的函数,然后将其添加到此函数的样本计数中。
我很确定是这种情况,但是想验证这是perf top
显示结果的方式,所以我写了一个快速测试程序来测试它的行为。该计划有两个感兴趣的功能outer
和inner
。 outer
函数在循环中调用inner
,inner
所做的工作量由参数控制。编译时一定要使用O0来避免内联。命令行参数控制两个函数之间的工作比率。
使用参数./a.out 1 1 1000000000
运行会得到结果:
49.20% a.out [.] outer
23.69% a.out [.] main
21.32% a.out [.] inner
使用参数./a.out 1 10 1000000000
运行会得到结果:
66.06% a.out [.] inner
17.77% a.out [.] outer
9.50% a.out [.] main
使用参数./a.out 1 100 1000000000
运行会得到结果:
88.53% a.out [.] inner
2.85% a.out [.] outer
1.09% a.out [.] main
如果inner
中包含outer
的计数,那么outer
的运行时百分比将始终高于inner
。但正如这些结果表明情况并非如此。
我使用的测试程序如下,并使用gcc -O0 -g --std=c11 test.c
编译。
#include <stdlib.h>
#include <stdio.h>
long inner(int count) {
long sum = 0;
for(int i = 0; i < count; i++) {
sum += i;
}
return sum;
}
long outer(int count_out, int count_in) {
long sum = 0;
for(int i = 0; i < count_out; i++) {
sum += inner(count_in);
}
return sum;
}
int main(int argc, char **argv) {
if(argc < 4) {
printf("Usage: %s <outer_cnt> <inner_cnt> <loop>\n",argv[0]);
exit(-1);
}
int outer_cnt = atoi(argv[1]);
int inner_cnt = atoi(argv[2]);
int loops = atoi(argv[3]);
long res = 0;
for(int i = 0; i < loops; i++) {
res += outer(outer_cnt, inner_cnt);
}
printf("res is %ld\n", res);
return 0;
}