2017-10-08 14 views
4

gprof를 사용하여 개발중인 일부 수치 코드를 프로파일 링하려하지만 gprof가 내 프로그램에서 데이터를 수집하지 못하는 것 같습니다. 여기 내 명령 줄이 있습니다 :gprof는 출력을 제공하지 않습니다.

g++ -Wall -O3 -g -pg -o fftw_test fftw_test.cpp -lfftw3 -lfftw3_threads -lm && ./fftw_test 

gmon.out 파일이 생성되었지만 데이터가없는 것으로 보입니다. 내가

gprof -b fftw_test gmon.out > gprof.out 

를 실행하면 내가 할 모든

Flat profile: 

Each sample counts as 0.01 seconds. 
    % cumulative self    self  total   
time seconds seconds calls Ts/call Ts/call name  


         Call graph 


granularity: each sample hit covers 2 byte(s) no time propagated 

index % time self children called  name 


Index by function name 

모든 통찰력은 무엇입니까?

코드는 많은 작업을 수행하지만 단순히 FFTW 루틴을 호출하지 않습니다. 그것은 특정 복소 계수를 계산하는 함수, 이러한 계수로 입력 데이터를 곱하는 함수 등을 포함합니다.

편집 : 예제 코드와 결과가 포함됩니다.

#include <cstdlib> 
#include <ctime> 

int main() 
{ 
    std::srand(std::time(0)); 

    double sum = 0.0; 

    for (int i = 0; i < RAND_MAX; ++i) 
     sum += std::rand()/(double) RAND_MAX; 

    std::cout << sum << '\n'; 

    return 0; 
} 

명령 라인 :

$ g++ -Wall -O3 -g -pg -o gprof_test gprof_test.cpp && ./gprof_test 
1.07374e+09 
$ gprof -b gprof_test gmon.out > gprof.out 
$ cat gprof.out 

결과 :

Flat profile: 

Each sample counts as 0.01 seconds. 
no time accumulated 

    % cumulative self    self  total   
time seconds seconds calls Ts/call Ts/call name  


         Call graph 


granularity: each sample hit covers 2 byte(s) no time propagated 

index % time self children called  name 


Index by function name 

그리고 그것 뿐이다.

+1

하나의 상호 작용이 아닌가요? 글쎄, 나는 리눅스 용 퍼펙트 툴을 시도해 보았지만 좋은 일을하는 것처럼 보이지만, 출력을 해석하는 것은 간단한 문제가 아니다. 저는 저의 "poor-man profiler"수업을 가지고 저를 도와 주었고 계산 시간을 상당히 줄였습니다. – Elias

+0

엘리아스, 이상합니다. Mike https://stackoverflow.com/users/23771/mike-dunlavey는 일반적으로 [프로파일 링]으로 태그 된 거의 모든 질문에서 통계적으로 입증되지 않은 특허 5 건의 무작위 백 트레이스 gdb 가난한 사람을 프로파일 링 할 것을 권장합니다. gprof가 손상되었을 수 있습니다. OS는 무엇입니까? 일부 데이터를 채우고 fftw를 빈 gprof 보고서로 호출하여 귀하의 사례를 테스트 할 수있게 해주는 간단한 프로그램 변형을 만들거나 (fftw lib 예제에서 찾을 수 있습니까?) – osgx

+1

간단한 기본 프로그램에서 동일한 문제가 있습니다. Archlinux에서 gcc 7.2.0 gprof 2.29.1. 그것은 무언가가 호환되지 않는 것처럼 보입니다. –

답변

-1

gprof가 내 프로그램에서 데이터를 수집하지 못하는 것처럼 보입니다.

g++ -Wall -O3 -g -pg -o fftw_test fftw_test.cpp -lfftw3 -lfftw3_threads -lm && ./fftw_test 

프로그램이 FFTW 라이브러리를 사용 아마도 거의 유일한 FFTW 라이브러리 호출의 구성 : 여기 내 명령 줄입니다. 실행 시간은 무엇입니까? 프로그램이 너무 빠르면 gprof로 프로파일 링 할 수 없습니다. 업데이트 그리고 gprof 프로파일 링을 사용하지 않고 컴파일 된 라이브러리는 gprof에서 볼 수 없습니다.

GNU gprof는 두 부분으로 구성됩니다. 첫째, 호출자/수신자 정보를 얻기 위해 -pg 옵션 (mcount 함수 호출 - https://en.wikipedia.org/wiki/Gprof)을 사용하여 컴파일 된 c/cpp 파일에서 함수 호출을 계측합니다. 둘째, 추가 프로파일 링 라이브러리를 실행 파일에 연결하여 주기적 샘플링을 추가하여 더 많은 시간 동안 실행 된 코드를 찾습니다. 샘플링은 profil (setitimer)로 수행됩니다. Setitimer 프로파일 링은 해상도가 제한되어 있으며 10ms 또는 1ms 미만의 간격 (100 또는 1000 샘플/초)을 해결할 수 없습니다.

예에서 fftw 라이브러리는 계측없이 컴파일되었으므로 mcount을 호출하지 않습니다. 여전히 샘플링 파트로 캡처 할 수 있지만 프로그램의 메인 스레드 (https://en.wikipedia.org/wiki/Gprof - "일반적으로 응용 프로그램의 메인 스레드 만 프로파일 링합니다")에서만 캡처 할 수 있습니다.

perf 프로파일 러는 아무런 장비가없는 mcount 100 또는 1000 Hz로하지 않고, (이 -g 옵션을 기록 할 때 긴장을 풀기 스택에서 수신자/발신자를 얻을 수)하지만 (이 하드웨어 PMU 카운터를 사용할 수 있습니다) 훨씬 더 통계/샘플링 변종이 제한하고 (프로필) 스레드를 올바르게 지원합니다. perf record -F1000 ./fftw_test (1 kHz 샘플링 주파수) 및 perf report 또는 perf report > report.txt을 시도하십시오."CPU 프로파일 러"에 대한 더 나은 setitimer은 스타일 프로파일 체크 구글 - perftools https://github.com/gperftools/gperftools를 들어 https://github.com/KDAB/hotspothttps://github.com/jrfonseca/gprof2dot

: 일부 GUI/HTML의 너무 PERF하는 프론트 엔드가있다.

======는 테스트와

가 나는 데비안 8.6 리눅스 커널 버전 3.16.0-4 - AMD64의 x86_64의 컴퓨터에서 일부 gprof의 결과를 가지고, g는 (데비안 4.9.2-10가), gprof은입니다 ++

$ cat gprof_test.cpp 
#include <cstdlib> 
#include <ctime> 
#include <iostream> 
int main() 
{ 
    std::srand(std::time(0)); 
    double sum = 0.0; 
    for (int i = 0; i < 100000000; ++i) 
     sum += std::rand()/(double) RAND_MAX; 
    std::cout << sum << '\n'; 
    return 0; 
} 
$ g++ -Wall -O3 -g -pg -o gprof_test gprof_test.cpp && time ./gprof_test 
5.00069e+06 
real 0m0.992s 
$ gprof -b gprof_test gmon.out 
Flat profile: 

Each sample counts as 0.01 seconds. 
no time accumulated 

    % cumulative self    self  total 
time seconds seconds calls Ts/call Ts/call name 
    0.00  0.00  0.00  1  0.00  0.00 _GLOBAL__sub_I_main 

그래서, gprof은이 일초 예를 언제든지 샘플을 잡아 라이브러리를 호출에 대한 정보 (-pg하지 않고 컴파일 된)를 가지고하지 않았다 "2.27 GNU gprof은 (데비안 GNU Binutils의)" . 일부 래퍼 함수를 ​​추가하고 인라인 최적화를 금지 한 후 내가 gprof은 그러나 라이브러리 시간에서 일부 데이터가 고려되지 않은이 (가 이초 런타임 0.72 초보고) :

$ perf record ./gprof_test 
0 
[ perf record: Woken up 2 times to write data ] 
[ perf record: Captured and wrote 0.388 MB perf.data (~16954 samples) ] 
$ perf report |more 
# Samples: 9K of event 'cycles' 
# Event count (approx.): 7373484231 
# 
# Overhead  Command  Shared Object      Symbol 
# ........ .......... ................. ......................... 
# 
    25.91% gprof_test gprof_test   [.] rand_scale1() 
    21.65% gprof_test libc-2.19.so  [.] __mcount_internal 
    13.88% gprof_test libc-2.19.so  [.] _mcount 
    12.54% gprof_test gprof_test   [.] main 
    9.35% gprof_test libc-2.19.so  [.] __random_r 
    8.40% gprof_test libc-2.19.so  [.] __random 
    3.97% gprof_test gprof_test   [.] rand_wrapper1() 
    2.79% gprof_test libc-2.19.so  [.] rand 
    1.41% gprof_test gprof_test   [.] [email protected] 
    0.03% gprof_test [kernel.kallsyms] [k] memset 
:

$ cat *cpp 
#include <cstdlib> 
#include <ctime> 
#include <iostream> 

int rand_wrapper1() 
{ 
    return std::rand(); 
} 
int rand_scale1() 
{ 
    return rand_wrapper1()/(double) RAND_MAX; 
} 
int main() 
{ 
    std::srand(std::time(0)); 
    double sum = 0.0; 
    for (int i = 0; i < 100000000; ++i) 
    sum+= rand_scale1(); 
//  sum += std::rand()/(double) RAND_MAX; 
    std::cout << sum << '\n'; 
    return 0; 
} 
$ g++ -Wall -O3 -fno-inline -g -pg -o gprof_test gprof_test.cpp && time ./gprof_test 
real 0m2.345s 
$ gprof -b gprof_test gmon.out 
Flat profile: 

Each sample counts as 0.01 seconds. 
    % cumulative self    self  total 
time seconds seconds calls ns/call ns/call name 
80.02  0.57  0.57        rand_scale1() 
19.29  0.71  0.14 100000000  1.37  1.37 rand_wrapper1() 
    2.14  0.72  0.02        frame_dummy 
    0.00  0.72  0.00  1  0.00  0.00 _GLOBAL__sub_I__Z13rand_wrapper1v 
    0.00  0.72  0.00  1  0.00  0.00 __static_initialization_and_destruction_0(int, int) [clone .constprop.0] 


         Call graph 


granularity: each sample hit covers 2 byte(s) for 1.39% of 0.72 seconds 

index % time self children called  name 
               <spontaneous> 
[1]  97.9 0.57 0.14     rand_scale1() [1] 
       0.14 0.00 100000000/100000000  rand_wrapper1() [2] 
----------------------------------------------- 
       0.14 0.00 100000000/100000000  rand_scale1() [1] 
[2]  19.0 0.14 0.00 100000000   rand_wrapper1() [2] 

그리고 반환 한 모든 부품을 본다

+0

그렇지 않습니다. 나는 큰 루프를 실행하는 프로그램을 사용하여 같은 행동을했습니다. – Elias

+0

일라이어스, 문제가있는 프로그램 예제를 온라인에 게시 할 수 있습니까? (빌드 지침 포함) – osgx

+0

질문을 편집했습니다. 나를 실행시키고 자하는 특정 코드 예제가 있다면, 나는 그것을 glaldy 할 것이다. – Elias