2009-06-16 9 views
8

GoogleのPerfツールを使い、CPUを大量に使用するアプリケーションのプロファイルを作成しようとしています。これは `ofstream 'を使って各ステップをファイルにダンプする統計的計算です。私はC++の専門家ではないので、ボトルネックを見つけるのに困っています。私の最初のパスは結果を与える:C++プロファイリング(google cpu perf tools)は正確に何を測定しますか?

 
Total: 857 samples 
    357 41.7% 41.7%  357 41.7% _write$UNIX2003 
    134 15.6% 57.3%  134 15.6% _exp$fenv_access_off 
    109 12.7% 70.0%  276 32.2% scythe::dnorm 
    103 12.0% 82.0%  103 12.0% _log$fenv_access_off 
     58 6.8% 88.8%  58 6.8% scythe::const_matrix_forward_iterator::operator* 
     37 4.3% 93.1%  37 4.3% scythe::matrix_forward_iterator::operator* 
     15 1.8% 94.9%  47 5.5% std::transform 
     13 1.5% 96.4%  486 56.7% SliceStep::DoStep 
     10 1.2% 97.5%  10 1.2% 0x0002726c 
     5 0.6% 98.1%  5 0.6% 0x000271c7 
     5 0.6% 98.7%  5 0.6% _write$NOCANCEL$UNIX2003 

すべての実計算がSliceStep :: DoStepで発生するので、これは、驚くべきことです。 "_write $ UNIX2003"(これは何かを知ることができますか?)は、出力ファイルの記述から来ているようです。今、私が混乱しているのは、outfile << "text"文をすべてコメントにしてpprofを実行すると、95%がSliceStep::DoStepにあり、 `_write $ UNIX2003 'がなくなるということです。しかし、私のアプリケーションは、合計時間で測定するとスピードアップしません。全体のスピードは1%未満です。

私には何が欠けていますか?

を追加しました: outfile <<文なしpprof出力は次のようになります。

 
Total: 790 samples 
    205 25.9% 25.9%  205 25.9% _exp$fenv_access_off 
    170 21.5% 47.5%  170 21.5% _log$fenv_access_off 
    162 20.5% 68.0%  437 55.3% scythe::dnorm 
     83 10.5% 78.5%  83 10.5% scythe::const_matrix_forward_iterator::operator* 
     70 8.9% 87.3%  70 8.9% scythe::matrix_forward_iterator::operator* 
     28 3.5% 90.9%  78 9.9% std::transform 
     26 3.3% 94.2%  26 3.3% 0x00027262 
     12 1.5% 95.7%  12 1.5% _write$NOCANCEL$UNIX2003 
     11 1.4% 97.1%  764 96.7% SliceStep::DoStep 
     9 1.1% 98.2%  9 1.1% 0x00027253 
     6 0.8% 99.0%  6 0.8% 0x000274a6 

これは、私が期待するもののように見える私は、パフォーマンスには目に見える増加(10秒計算上0.1秒)を参照してくださいしない以外。コードは本質的に次のとおりです。

アップデート:私は、プロファイラーの開始位置と終了位置を開始するboost :: timerを使用してタイミングを調整します。私はスレッドや何か幻想的なものを使用しません。

+0

どのようにランタイムを測定しますか? 両方の設定で「time ./yourprogramm」を実行します。 マルチスレッドを使用していますか? – ebo

+0

時間とともに実行し、sys/usr時間を測定します。プロファイラー番号は、出力なしで実行時間が40%少なくなければならないことを示しています。最も簡単な説明は、プロファイラの測定値が歪んでいることです。 – ebo

+0

これはユーザーのすべてです。私がやっていることはかなり単純です、私はそう思います...ファイルが全期間開いているという事実は何を意味するのでしょうか? – Tristan

答えて

3

:あなたはプロファイラから取得

数字は、プログラムがprint文なしで約40%高速であることを、言います。

ランタイムはほぼ同じです。

明らかに測定値の1つが間違っていなければなりません。つまり、より多くの測定を行う必要があります。

まずは別の簡単なツールで始めることをお勧めします。これはあなたの時間がどこに費やされているかを大まかに知るはずです。

  • を測定する前にウォームアップを行い、より大きな問題
  • を使用します。結果はまだ決定的でない場合

    方が良いテストケースを必要としています。いくつかのループを行い、後で(同じプロセスで)測定を開始します。


Tiristan:それはすべてのユーザーにあります。私がやっていることはかなり単純です、私は思う...ファイルが全体的に開いているという事実は、何かを意味しますか?

これは、プロファイラが間違っていることを意味します。

印刷のようなものでPythonの結果を使用してコンソールに100000本のライン:

for i in xrange(100000): 
    print i 

コンソールへ:

time python print.py 
[...] 
real 0m2.370s 
user 0m0.156s 
sys  0m0.232s 

バーサス:

time python test.py > /dev/null 

real 0m0.133s 
user 0m0.116s 
sys  0m0.008s 

私のポイントは次のとおりです。 あなたの内部の尺度時間は、出力を無効にすることから何も得られないことを示しています。 Google Perfツールでは、必要があると言われています。誰が間違っている?

+0

操作には10秒かかりますが、基本的にSlice :: DoStep関数の近くにあります。私は_writeがどのように離れていくのか理解していません。40%の後で、影響はありません。 – Tristan

+0

それがポイントです。 1つの番号が間違っている必要がありますどちらを見つけるか。プロファイラが生成する数値は、統計的に有意ではないか、または間違っている可能性があります。 – ebo

1

_write $ UNIX2003はおそらく、端末に出力するwrite POSIXシステムコールを参照しています。 I/Oは他のほとんどのものと比較して非常に遅いので、かなりの量の出力を書いていると、プログラムがそこに多くの時間を費やしていることは意味があります。

出力を削除してもプログラムがスピードアップしない理由はわかりませんが、あなたが与えた情報だけを推測することはできません。 cout文が削除されたときに、コードの一部を表示したり、perftoolsの出力を表示したりするのはいいでしょう。私のコメントから

1

Google perftoolsはコールスタックのサンプルを収集します。そのため、必要なものは、それらを可視化することです。

文書によれば、呼び出しグラフを文またはアドレスの細かさで表示できます。それはあなたが知る必要があることを教えてくれるはずです。

関連する問題