2011-02-16 4 views
4

Linux에서 실행되는 몇 가지 매우 간단한 C++ 프로그램을 프로파일 링했습니다. main()의 포괄적 인 비용은 모두 3.83 %와 같이 100 %가 아닙니다. callgrind를 올바르게 사용하고 있습니까? 아래에 --inclusive=yes이 붙여진 callgrind_annotate의 결과가 있습니다.Callgrind main() 포함 비용이 100 %보다 훨씬 작음

프로그램은 단순한 힙 정렬을 수행하는 힙이라고합니다. I가 사용되는 명령은 그 다음, I 입력

valgrind --tool=callgrind ./heap 

이다

callgrind_annotate --inclusive=yes callgrind.out.25434 

출력 : main() 통화 그래프 가기 기능없는

`-------------------------------------------------------------------------------- 

Profile data file 'callgrind.out.25434' (creator: callgrind-3.6.0) 

`-------------------------------------------------------------------------------- 

I1 cache: 
D1 cache: 
LL cache: 
Timerange: Basic block 0 - 361578 
Trigger: Program termination 
Profiled target: ./heap (PID 25434, part 1) 
Events recorded: Ir 
Events shown:  Ir 
Event sort order: Ir 
Thresholds:  99 
Include dirs: 
User annotated: 
Auto-annotation: off 

`-------------------------------------------------------------------------------- 

     Ir 
`-------------------------------------------------------------------------------- 

2,552,558 PROGRAM TOTALS 

`-------------------------------------------------------------------------------- 

     Ir file:function 

`-------------------------------------------------------------------------------- 

2,552,558 ???:0x00000810 [/lib/ld-2.7.so] 

2,515,793 ???:0x00000a60 [/lib/ld-2.7.so] 

2,515,219 ???:0x00015270 [/lib/ld-2.7.so] 

2,514,780 ???:0x000021e0 [/lib/ld-2.7.so] 

2,456,164 ???:0x0000b2f0 [/lib/ld-2.7.so] 

2,256,719 ???:0x00009e40 [/lib/ld-2.7.so] 

1,702,371 ???:0x00009ac0 [/lib/ld-2.7.so] 

    657,883 ???:0x000098e0 [/lib/ld-2.7.so] 

    367,045 ???:0x00017040 [/lib/ld-2.7.so] 

    33,170 ???:0x080483e0 [/home/test/heap] 

    33,036 ???:0x0000ce60 [/lib/ld-2.7.so] 

    31,347 ???:0x0000e850 [/lib/ld-2.7.so] 

    30,706 ???:(below main) [/lib/libc-2.7.so] 

    30,071 ???:0x00008570 [/lib/ld-2.7.so] 

    27,954 ???:0x0000f500 [/lib/ld-2.7.so] 

    27,758 ???:0x0000ca30 [/lib/ld-2.7.so] 

    21,366 ???:0x0001767b [/lib/ld-2.7.so] 
+0

최소한 출력물 중 일부가 누락 된 것 같습니다. 특히, 나는 포함 된 비용 수치를 보지 못합니다. 프로그램이 실행되기까지 얼마나 걸립니까? 더 오래 걸릴 수 있도록 배열하면 (예 : 힙 배열이 훨씬 긴 배열), 포괄 비용이 100 %에 더 가깝습니까? main()이 호출되기 전에 런타임에서 수행하는 작업은 모두 계산되지 않으므로 main()이 동적 라이브러리를로드하는 것보다 훨씬 저렴하면 포함 된 비용이 100 % 미만의 어떤 방법이 될 수 있습니다. 절대 단위로 부족한 부분은 무엇입니까 (예 : ms)? –

+0

감사합니다 Gareth! 힙 정렬은 1 초 미만입니다. 나는 그것을 더 오랫동안 돌릴 것이다. 내가 callgrind를 올바르게 사용하고 있는지 확인하고 싶습니다. 실제 응용 프로그램을 프로파일 링 할 때 callgrind로 식별되는 큰 병목 현상 (47 % 만 제거)을 수행 한 이후로 전체 실행 시간이 전혀 변경되지 않습니다. – Shawn

답변

4

. glibc에는 _start 함수가 있으며 main()을 호출하며 main에서 반환 값을 가져옵니다. 동적 인 링커 (런타임)라고도 알려진 ELF 인터프리터가 있습니다 : /lib/ld-linux.so (이 이름은 리눅스에서, 다른 유닉스에서는/lib와 같은 것으로 사용됩니다 /ld.so). 링커는 응용 프로그램에 필요한 모든 동적 라이브러리를로드하고 초기화합니다. _start 전에 OS에서 호출됩니다.

main 전에 수행 할 작업은 무엇입니까? 라이브러리로드 (라이브러리 파일 열기, 헤더 압축, mmap, 메모리 위치 변경 코드 재배치) 및 초기화 (동적 및 통계적으로 링크 된 라이브러리 모두 필요하지만 glibc = libc도 라이브러리 임) . 각 라이브러리에는 라이브러리가로드 된 직후에 시작될 코드가있을 수 있습니다 (__attribute__((constructor)) 또는 전역 객체의 중요하지 않은 생성자). 또한, glibc는 메인 뒤에서 실행할 일부 함수를 등록 할 수 있습니다 (예 : atexit()을 통해, 메인이 정상적으로 리턴하면 _start가 호출합니다). 라이브러리는 전역 오브젝트에 대한 소멸자 함수를 가질 수 있습니다.

프로그램 스레드를 사용하는 경우, 스레드 1의 정상 기능 .. n는 메인 (각 스레드 스택을 분리 할 수 ​​및 기능의 체인 main으로부터 스레드 0의 스택 에 저장되는) 호출되지 않을 것이다.

예제에서 우리는 /lib/ld-*.so를보고 동적 링커입니다. 응용 프로그램 실행이 너무 짧아서 올바르게 프로파일 링되지 않으며 많은 수의 동적 라이브러리가 사용됩니다.

관련 문제