我使用perf -g -p
显示我的样本的perf输出。
我不知道如何解释有很多条目需要> 90%的时间。毕竟,如果某个进程在start_thread
(及其子级)中花费了90%的时间,则该进程不可能花费>在java_start
(例如)中也有90%的时间。
请解释
答案 0 :(得分:2)
让我们从您用于执行perf record
。
使用-g
开关表示您正在尝试收集有关调用链的信息以及有关开销的信息。
当perf收集调用链时,开销可以在两列中显示为儿童和自我。
Children Self Command Shared Object Symbol ◆
- 14.19% 0.00% qemu-system-x86 [unknown] [.] 0xbbbe258d4c544155 ▒
0xbbbe258d4c544155 ▒
__libc_start_main ▒
+ main ▒
自我'开销值表示在单个函数中花费的计时器滴答(周期值)的计数。因此,如果只有自我'开销值将显示在perf report
中,开销值之和总是 100%,正如您可能期望的那样。
然而,当两个孩子都在一起时和'自我'列在perf report
中显示,事情变得更加混乱。孩子'开销列总结了从父级调用的所有子函数的开销值。
在您的情况下,start_thread
有一个孩子'管理费用率为98.78%,但其自身比率为98%。开销为0.00%。这意味着start_thread
(即子函数)调用的所有函数中执行所花费的时间总和为98.78%,但仅start_thread
不会导致任何管理费用,因为它的自我'开销为0.00%。
现在来Java_start
。看似start_thread
次来电Java_start
。再一次,孩子们' Java_start
的开销将包括它调用的所有函数的开销总和。这就是为什么你再次看到两个函数的开销值几乎相同。
考虑一个例子 -
void main(){
do_main();
}
void do_main() {
foo();
}
void foo(){
bar();
}
void bar(){
/* do something here */
}
让我们假设自己' foo()
和bar()
的开销分别为60%和40%。并且让main()
和do_main()
各自拥有自我'开销分别为0%和0%。
然后孩子'每个函数的开销都是 -
main() children: 100% self: 0%
do_main() children: 100% self: 0%
foo() children: 100% self: 60%
bar() children: 40% self: 40%