2

GNU gprof 2.15.94.0.2.2 を使用して、呼び出しサイクルが大きい C++ プログラムのプロファイリングを行います。gprof のドキュメントに示されているように、コール グラフの出力に次のようなものが表示されることを期待していました。

index  % time    self  children called     name
----------------------------------------
                 1.77        0    1/1        main [2]
[3]     91.71    1.77        0    1+5    <cycle 1 as a whole> [3]
                 1.02        0    3          b <cycle 1> [4]
                 0.75        0    2          a <cycle 1> [5]
                    0        0    6/6        c [6]
----------------------------------------

ただし、私の<cycle as a whole>エントリには発信者がリストされていません。それらはすべて次のようになります。

index  % time    self  children called             name
----------------------------------------------
[8]     65.6    259.55  5342.63  9334767+60122608 <cycle 2 as a whole> [8]
                133.28  2051.45  12043564+74015448    foo <cycle 2> [14]
                18.90   976.38   2379645              bar <cycle 2> [21]
...                                                                      
-----------------------------------------------

私のサイクルは非常に大きいので、サイクル内の個々の関数を介して呼び出し元を追跡するのは非常に困難です。

出力にサイクル呼び出し元が表示されない理由と、それらを表示させる方法を誰か教えてもらえますか?

4

3 に答える 3

1

あなたのアプリケーションはマルチスレッドを使用していますか? gprof はスレッドではまったく機能しません。そうしないと、gprof のバグに遭遇する可能性が非常に高くなります。それはバグだらけで時代遅れです。oprofile や valgrind などを使用することをお勧めします。

于 2009-11-24T16:34:45.737 に答える
0

これを gprof のバグと呼ぶことにします。相互再帰関数の簡単な例を設定したところ、まったく同じ動作が得られました。私は機能を持っていました:

int a(int n){return b(n);}
int b(int n){return c(n);}
int c(int n){return (n==0)?n:a(n-1);}

および main():

for(int j=0; j <1000; ++j)
  for(int i=0; i < 10; ++i)
     cout << a(i);

a() への呼び出しを次のように置き換えてみました。

int d(int n){return a(n);}

gprof が main() からの呼び出しよりも d() からのサイクルへの呼び出しを登録することを期待していましたが、同じ結果が得られました。

また、cout を printf() に置き換えて C プログラムを作成しましたが、サイクルの呼び出し元がリストされていないという同じ結果が得られました。

于 2009-11-23T19:32:16.793 に答える
0

これが主な関心事ですか、それとも、最適化できるものを見つけようとするなど、より大きな目標がありますか? 通常、それがgprofを使用する理由です。

gprofはそれが何であるかですが、もっとうまくやることができます。

于 2009-11-23T19:45:42.257 に答える