4

に従って、gprofを受け取る C++ プログラムを実行したところ、出力の最初の行で次のようになりました。16.637stime()

%   cumulative   self              self     total           
time   seconds   seconds    calls   s/call   s/call  name    
31.07      0.32     0.32  5498021     0.00     0.00  [whatever]

数秒31.07%しかかからなかったのに、なぜ時間がリストされるのですか? .32これは通話時間ですか?(self s/call ではないでしょうか?)

を使うのはこれが初めてgprofなので、親切にしてください:)

編集: 下にスクロールすると、gprof は私のプログラムが 1.03 秒しかかからないと考えているようです。なぜそれがそれほど間違っているのでしょうか?

4

6 に答える 6

9

ボトルネックはファイル I/O にあることが判明しました ( Is std::ifstream は FILE より大幅に遅いですか?を参照してください)。バッファ内のファイル全体を読み取るように切り替えたところ、非常に高速になりました。

ここでの問題は、ファイル I/O を待っているときに gprof が正確なプロファイリングを生成していないように見えることでした ( http://www.regatta.cs.msu.su/doc/usr/share/man/info/ru_RU/a_doc_libを参照)。 /cmds/aixcmds2/gprof.htm )。実際、seekgtellgはプロファイリング リストにも載っておらず、ボトルネックでした。

于 2009-02-01T21:04:43.880 に答える
6

自己秒は[何でも]に費やされた時間です。

累積秒数は、[whatever]とその上の呼び出し([whatever] + mainなど)に費やされた時間です。

どちらにも、[何でも]から呼び出された関数に費やされた時間は含まれていません。 そのため、リストされている時間がこれ以上表示されません。

たとえば、[whatever]関数が多くのprintfを呼び出している場合、gprof出力は、printfがその時間の大部分を消費していることを示しています。

于 2009-01-27T23:53:52.987 に答える
2

これは、 gprof の出力を読み取る方法のかなり良い概要のようです。あなたが見ている 31.07% は、gprof がその関数だけで費やされていると考える総実行時間の一部です (それが呼び出す関数は含みません)。オッズは、時間が小さいのにパーセンテージが非常に大きい理由は、gprof がプログラムがあなたほど長くかからないと考えているためです。これは、gprof 出力の最初のセクションを下にスクロールすることで簡単に確認できます。累積秒数は、プログラムの合計実行時間 (gprof の観点から) で制限されるまで、どんどん大きくなり続けます。これは、予想している 16 秒ではなく、約 1 秒であることがわかると思います。

なぜそこに大きな違いがあるのか​​ については、私には言えません。gprof がすべてのコードを認識していない可能性があります。それとも、プロファイリング中にインストルメント化されたコードで時間を使用しましたか? 私はそれが正しく機能するとは思わないでしょう...

于 2009-01-28T22:58:55.813 に答える
1

この質問に記載されている他のツールをいくつか試しましたか? それらがどのように比較されるかは興味深いでしょう。

于 2009-01-28T00:23:01.540 に答える
1

gprofや同じ概念に基づく他のプロファイラーに共通する問題が発生しています。1) プログラム カウンターをサンプリングしてある種のヒストグラムを取得する、2) 関数をインストルメント化して時間、カウントを測定し、呼び出しグラフを取得します。

パフォーマンスの問題を実際に特定するには、ポイントを逃しています。
ルーチンを測定することではなく、問題のあるコードを見つけることです。

ランダムな壁時計の時刻にプログラムをストロボスコープで X 線撮影するサンプラーがあるとします。各サンプルでは、​​プログラムは I/O の途中にある場合もあれば、コンパイルしたコードにある場合もあれば、mallocなどのライブラリ ルーチンにある場合もあります。

しかし、どこにいても、その時間の一部を費やす責任は、コール スタック上のコードのすべての行によって共同で共有されます。その呼び出しによって要求された作業を終了します。

したがって、コール スタックの複数のサンプルに表示されるすべてのコード行に注目してください (サンプルが多いほど良い)。そこがお金です。プログラムカウンターがどこにあるかだけを見ないでください。スタックの上位には「深いポケット」があります。

于 2009-11-23T21:22:04.497 に答える
0

はい、これらの「秒」の値呼び出しごとではありません。パーセンテージ時間は、プログラムの実行全体に対するものです。実際、プログラムはその関数で時間の 31% を費やしました (呼び出しの数 + 呼び出しごとにかかる時間による)。

gprof のフラット プロファイルを分析する方法を読みたいと思うかもしれません。

訂正:申し訳ありませんが、OP で指摘されているように、最初の 2 秒の値は累積的です。

「self」と「total s/call」が 0 になっているのはおかしいと思います。

gprof の精度に関するセクションの引用: 「実際のエラー量は、通常、1 サンプリング周期よりも大きくなります。実際、値がサンプリング周期の n 倍である場合、その値の予想される誤差は、n サンプリング周期の平方根です。サンプリング期間は 0.01 秒で、foo の実行時間は 1 秒であり、foo の実行時間で予想される誤差は 0.1 秒です.プロファイリングの実行ごとに平均でこれだけ変動する可能性があります.もっと。)"

また、関連している可能性がありますが、gprof はマルチスレッド プログラムをプロファイリングしないことに注意してください。そのような場合は、 SysprofOProfileなどを使用することをお勧めします。

于 2009-01-27T22:48:46.940 に答える