2017-10-08 4 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

1つのインタラクションはありませんか? Linux用のperfツールを試してみましたが、うまくやっているようですが、出力を解釈するのは簡単ではありません。私は仕事を手伝うために自分自身の「貧乏人プロファイラ」クラスを考え出し、計算時間をかなり短縮しました。 – Elias

+0

エリアス、これは変です。 Mike https://stackoverflow.com/users/23771/mike-dunlaveyは、[プロファイリング]でタグ付けされたほとんどすべての質問で、彼の特許ではない統計的に証明された5つのランダムバックトレースgdbの貧乏人のプロファイリングをお勧めします。あなたのgprofが壊れているかもしれませんが、OSは何ですか?いくつかのデータを埋めるプログラムの簡単な変形を作成(またはfftw libの例で見つけること)できますか?空のgprofレポートでfftwを呼び出すと、あなたのケースをテストできますか? – 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には2つの部分があります。まず、-pgオプション(mcount関数呼び出し - https://en.wikipedia.org/wiki/Gprof)でコンパイルされたc/cppファイルの関数呼び出しを呼び出して、呼び出し元/呼び出し先情報を取得します。第2に、追加のプロファイリングライブラリを実行可能ファイルにリンクして、定期的なサンプリングを追加して、より多くの時間実行されたコードを見つけます。サンプリングはprofil(setitimer)で行います。 Setitimerプロファイリングは解像度が制限されており、10 msまたは1 ms(1秒あたり100または1000サンプル)未満の間隔を解決することはできません。

あなたの例では、fftwライブラリはおそらく計装なしでコンパイルされているため、mcountは呼び出されませんでした。それはまだサンプリング部分でキャプチャすることができますが、プログラムのメインスレッド(https://en.wikipedia.org/wiki/Gprof - "通常はアプリケーションのメインスレッドのみをプロファイルします")にのみキャプチャできます。

perfプロファイラ100または1000ヘルツせずに、(それは、ハードウェアのPMUカウンタを使用することができます)(それは-gオプションで記録したときに巻き戻し、スタックから呼び出し先/発信者を取得します)mcountとは機器を持っていないが、それははるかに良い統計/サンプリングバリアントを持っていますそれは、(プロファイル)スレッドを正しくサポートします。 perf record -F1000 ./fftw_test(1 kHzサンプリング周波数)とperf reportまたはperf report > report.txtを試してください。https://github.com/KDAB/hotspothttps://github.com/jrfonseca/gprof2dot

"CPU PROFILER"については、google-perftools https://github.com/gperftools/gperftoolsを確認してください。私はDebianの8.6 Linuxカーネルのバージョン3.16.0-4-のamd64 x86_64のマシン、G ++(Debianの4.9.2-10)にいくつかのgprofの結果を持って、あなたのテストでは

======

、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のは、この1秒の例では任意の時間サンプルをキャッチし、ライブラリへの呼び出しに関する情報(彼らは-pgなしでコンパイルされた)を持っていませんでした「2.27 GNU gprofを(DebianのためのGNU Binutilsの)」 。一部のラッパー関数を追加し、インラインの最適化を禁止した後、私はいくつかのgprofのデータが、ライブラリの時間を持っている(それが2秒ランタイムの0.72秒を見て)計上されなかった。

$ 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] 

そしてPERFは、すべての部分を見ている:

$ 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 
+0

これはそうではありません。私は大きなループを実行するプログラムを使用して同じ動作があります。 – Elias

+0

エリアス、問題のあるプログラムの例をオンラインで投稿できますか(ビルド手順は?) – osgx

+0

私は質問を編集しました。私に実行させたい特定のコード例がある場合、私はそれをglaldyします。 – Elias

関連する問題