리눅스 Perf 리포트 출력 이해
대부분의 결과를 직관적으로 얻을 수 있지만, 결과를 완전히 이해하는 데 어려움을 겪고 있습니다.perf report
특히 통화 그래프와 관련된 것에 대해 명령을 내리기 때문에, 저는 이 문제를 모두 해결하기 위해 바보 같은 테스트를 작성했습니다.
바보같은 시험.
다음 내용을 정리했습니다.
gcc -Wall -pedantic -lm perf-test.c -o perf-test
인라인 등을 피하기 위한 적극적인 최적화는 없습니다.
#include <math.h>
#define N 10000000UL
#define USELESSNESS(n) \
do { \
unsigned long i; \
double x = 42; \
for (i = 0; i < (n); i++) x = sin(x); \
} while (0)
void baz()
{
USELESSNESS(N);
}
void bar()
{
USELESSNESS(2 * N);
baz();
}
void foo()
{
USELESSNESS(3 * N);
bar();
baz();
}
int main()
{
foo();
return 0;
}
플랫 프로파일링
perf record ./perf-test
perf report
이를 통해 다음을 얻을 수 있습니다.
94,44% perf-test libm-2.19.so [.] __sin_sse2
2,09% perf-test perf-test [.] sin@plt
1,24% perf-test perf-test [.] foo
0,85% perf-test perf-test [.] baz
0,83% perf-test perf-test [.] bar
과중한 작업이 실제로 수행되기 때문에 합리적인 것 같습니다.__sin_sse2
그리고.sin@plt
제 기능의 오버헤드는 루프만을 고려하는 반면, 아마도 래퍼일 것입니다.3*N
에 대한 반복.foo
,2*N
나머지 둘은.
계층 프로파일링
perf record -g ./perf-test
perf report -G
perf report
이제 오버헤드 열은 두 개입니다.Children
(출력은 기본적으로 이 값으로 정렬됩니다) 및Self
(평판 프로파일의 동일한 오버헤드).
여기서 제가 뭔가 그립다는 느낌을 받기 시작합니다. 제가 사용하는 사실에 상관없이.-G
예를 들어 "x calls y" 또는 "y는 x에 의해 호출된다"는 식으로 계층 구조를 설명할 수 없습니다.
없이.
-G
("y"는 x로 부름):- 94,34% 94,06% perf-test libm-2.19.so [.] __sin_sse2 - __sin_sse2 + 43,67% foo + 41,45% main + 14,88% bar - 37,73% 0,00% perf-test perf-test [.] main main __libc_start_main - 23,41% 1,35% perf-test perf-test [.] foo foo main __libc_start_main - 6,43% 0,83% perf-test perf-test [.] bar bar foo main __libc_start_main - 0,98% 0,98% perf-test perf-test [.] baz - baz + 54,71% foo + 45,29% bar
- 왜죠
__sin_sse2
부름을 받습니다.main
(indirect적으로?)foo
그리고.bar
하지만 그렇지는baz
? - 함수들이 때때로 백분율과 계층을 첨부하는 이유(예: 마지막 인스턴스)
baz
) 및 때로는 그렇지 않습니다(예: 마지막 사례).bar
)?
- 왜죠
와 함께
-G
("x call y"):- 94,34% 94,06% perf-test libm-2.19.so [.] __sin_sse2 + __sin_sse2 + __libc_start_main + main - 37,73% 0,00% perf-test perf-test [.] main - main + 62,05% foo + 35,73% __sin_sse2 2,23% sin@plt - 23,41% 1,35% perf-test perf-test [.] foo - foo + 64,40% __sin_sse2 + 29,18% bar + 3,98% sin@plt 2,44% baz __libc_start_main main foo
- 아래의 처음 3개 항목을 어떻게 해석해야 합니까?
__sin_sse2
? main
부름foo
그리고 그건 괜찮아요, 하지만 만약 전화가 온다면 왜요?__sin_sse2
그리고.sin@plt
(indirect적으로?)그것은 또한 부르지 않습니다.bar
그리고.baz
?- 왜 그럴까요?
__libc_start_main
그리고.main
의 밑에 나타나다foo
? 그 이유는foo
두 번이나 나타나나요?
- 아래의 처음 3개 항목을 어떻게 해석해야 합니까?
두 번째 단계는 실제로 "x calls y"/"y"를 나타내는 두 단계의 계층 구조가 있는 것으로 의심되지만, 추측하는 데 지쳐서 여기에 묻습니다.그리고 그 문서는 도움이 되지 않는 것 같습니다.
글이 길어서 미안하지만 이 모든 맥락이 다른 사람에게도 도움이 되거나 참고가 되기를 바랍니다.
좋아요, 그럼 발신자와 발신자 통화 그래프 사이의 차이를 잠시 무시해 봅시다. 대부분 제 기계에서 이 두 옵션 사이의 결과를 비교할 때 내부에서만 효과가 나타나기 때문입니다.kernel.kallsyms
제가 이해할 수 없는 이유로 DSO를 사용합니다. 저 자신은 비교적 이 일을 처음 접합니다.
예를 들어, 나무 전체를 읽는 것이 좀 더 쉽다는 것을 알았습니다.그래서 사용.--stdio
에 대해 나무 __sin_sse2
:
# Overhead Command Shared Object Symbol
# ........ ......... ................. ......................
#
94.72% perf-test libm-2.19.so [.] __sin_sse2
|
--- __sin_sse2
|
|--44.20%-- foo
| |
| --100.00%-- main
| __libc_start_main
| _start
| 0x0
|
|--27.95%-- baz
| |
| |--51.78%-- bar
| | foo
| | main
| | __libc_start_main
| | _start
| | 0x0
| |
| --48.22%-- foo
| main
| __libc_start_main
| _start
| 0x0
|
--27.84%-- bar
|
--100.00%-- foo
main
__libc_start_main
_start
0x0
가 이걸 은 44%입니다sin
됩니다에서 됩니다.foo
전화를 27%는 를 받습니다.baz
27%는 는에서.
-g에 대한 설명서는 유용합니다.
-g [type,min[,limit],order[,key]], --call-graph
Display call chains using type, min percent threshold, optional print limit and order. type can be either:
· flat: single column, linear exposure of call chains.
· graph: use a graph tree, displaying absolute overhead rates.
· fractal: like graph, but displays relative rates. Each branch of the tree is considered as a new profiled object.
order can be either:
- callee: callee based call graph.
- caller: inverted caller based call graph.
key can be:
- function: compare on functions
- address: compare on individual code addresses
Default: fractal,0.5,callee,function.
여기서 중요한 점은 기본값이 프랙탈이고 프랙탈 모드에서는 각 분기가 새로운 개체라는 것입니다.
를 하는 baz
고에서bar
, 그리고 나머지 50%의 사람들은 그들로부터 전화를 받습니다.foo
.
한 척도는 를 를 살펴보는 -g graph
:
94.72% perf-test libm-2.19.so [.] __sin_sse2
|
--- __sin_sse2
|
|--41.87%-- foo
| |
| --41.48%-- main
| __libc_start_main
| _start
| 0x0
|
|--26.48%-- baz
| |
| |--13.50%-- bar
| | foo
| | main
| | __libc_start_main
| | _start
| | 0x0
| |
| --12.57%-- foo
| main
| __libc_start_main
| _start
| 0x0
|
--26.38%-- bar
|
--26.17%-- foo
main
__libc_start_main
_start
0x0
이는 해당 콜 체인에 대해 각 시간 비율이 보고되는 절대 비율을 사용하는 것으로 바뀝니다.foo->bar
는 는 다시의 26%다됨)를 호출됩니다.baz
및 ).foo->baz
(직접)은 전체 눈금의 12%입니다.
발신자 사이에 가 없는를 아직도 .__sin_sse2
.
갱신하다
당신의 명령 줄에서 제가 바꾼 한가지는 통화 그래프가 어떻게 모였는지 입니다.Linux perf는 기본적으로 호출 스택을 재구성하는 프레임 포인터 방법을 사용합니다.다를 때 이 가 발생할 수 .-fomit-frame-pointer
채무 불이행으로그래서 제가.
perf record --call-graph dwarf ./perf-test
언급URL : https://stackoverflow.com/questions/27742462/understanding-linux-perf-report-output
'source' 카테고리의 다른 글
오류 메시지와 함께 SQL 쿼리에 대한 도움이 필요합니다. Operand에는 열 1개가 포함되어야 합니다. (0) | 2023.10.14 |
---|---|
자바스크립트를 이용하여 Ctrl+V, Ctrl+C를 검출하는 방법? (0) | 2023.10.14 |
WCF 웹 서비스 요청의 XML SOAP 요청을 받으려면 어떻게 해야 합니까? (0) | 2023.10.09 |
쿼리가 두 번째로 실행되면 더 빨리 실행됩니다. 이를 중지하려면 어떻게 해야 합니까? (0) | 2023.10.09 |
자바스크립트에서 이진수를 나타내는 "0b" 등이 있습니까? (0) | 2023.10.09 |