18

実行時間の観点から既存のコードをプロファイリングするという点で、いくつかの助けが必要です。意図はそれをスピードアップすることです。

以前に作業したコードがいくつか与えられました。これは、オブジェクト指向の概念を使用して完全にC++で記述されています。これにはGUIベースのインターフェイスがあり、特定のオプションを選択すると、選択したコードが実行されます。(プロジェクトの一環として約11のクラスがあります)。

GUIオプションを押して、コードを実行し、次のようなリソースマップを生成できるようにしたいです。

Functions of Class 1 = 20% of execution time
Functions of Class 2 = 60% of execution time
Functions of Class 3 = 10% of execution time
Functions of Class 4 = 10% of execution time

そうすることで、どのクラスが最も時間を費やしているかがわかり、次にどのクラスに取り組み、改善するかがわかります。しかし、私はこれをどうやってやるのか分かりません。私は基本的なC++の知識しか持っていません。

私はこの投稿を読みました:プログラムはシリアルではないので、c++の実行時間を見つけてください。あるクラスが別のクラスを呼び出し、それが別のクラスを呼び出します。システムクロック/ティックがどのように実装可能かわかりませんか?

Valgrind、Zoom、Poor Man's Profilerなどのプログラムを読んだのですが、正直なところ、それをコードと統合することについてはわかりません。こんなに簡単な方法はありますか?

私もこの方法を読みました:Linuxで実行されているC ++コードをプロファイリングするにはどうすればよいですか?、しかし、クラスベースの情報(クラス1、クラス2など)に関してピンポイントの情報を取得する方法がわかりません。

誰かが初心者のためにアドバイスしてもらえますか?

4

3 に答える 3

17

Valgrind(サブツールcallgrind)の使い方は非常に簡単です。callgrindが呼び出されるさまざまな関数の名前を見つけられるように、十分なデバッグ情報がプログラムにコンパイル/リンクされていることを確認する必要があります。次に、プログラムを直接呼び出す代わりに、次のように、プログラム(およびその引数)をパラメーターとしてvalgrindに渡します。

valgrind --tool=callgrind --trace-children=yes <myprogram> <myprogram_args>

(--trace-childrenは、実際の実行可能ファイルがラッパースクリプトのいくつかのレイヤーの背後に隠れている場合に使用されます)

すべての関数エントリポイントがトレースされるため、プログラムの実行速度ははるかに遅くなります(100倍遅くなるなど)。

callgrindの出力を探索するためのさまざまなツール、特にkcachegrind/qcachegridが存在します。

または、少数の高レベル関数のシステムクロックティックを測定し(「関数Xとその下のすべてにかかる時間」が表示されます)、ホットスポットを見つけたらコードを進めます。

このようなもの(概念的には、ヘッダー/ソースに適切に編成する必要があります):

struct FunctionTimer {
  FunctionTimer(char const * name) : mName(name), mStartTime(clock()) { }
  ~FunctionTimer() { mFunctionTimes[mName] += clock() - mStartTime; }

  static void report()
  {
    ... iterate through mFunctionTimes, printing out
    the names and accumulated ticks ...
  }

  std::string mName;
  clock_t mStartTime;

  static std::map<std::string, clock_t> mFunctionTimes;
};

...

void myfunc()
{
  FunctionTimer ft("myfunc");
  ... code of myfunc ...
}

...

int main(int argc, char* argv[])
{
  ... do stuff ...
  FunctionTimer::report();
}
于 2012-06-13T00:40:52.617 に答える
2

醜い解決策は、関心のある各関数の周りでタイマーを開始および停止し、各呼び出しの後にグローバル変数に時間を追加することです。次に、メインの最後で、変数を比較してパーセント時間を計算します。

ただし、これは、特に関数がたくさんある場合は、非常に大きくなる可能性があります。C ++のアスペクト指向フレーバーに精通している場合は、一時的にそれを使用できます。アスペクトを使用すると、すべての関数にボイラープレートコードを簡単に配置できるからです。

于 2012-06-13T00:29:39.180 に答える
2

ウィキペディアには、 cおよびc++のパフォーマンス分析ツールの優れたリストがあります。それらが役立つかどうかを確認してください。

于 2012-06-13T00:43:20.920 に答える