5

Linuxで実行されているいくつかの非常に単純なC++プログラムのプロファイルを作成しました。それらすべてのmain()の包括的コストは、100%からはほど遠い、3.83%のようなものです。callgrindを正しく使用していますか?以下に貼り付けたcallgrind_annotatewithの出力があります。--inclusive=yes

このプログラムはヒープと呼ばれ、単純なヒープソートを実行します。私が使用したコマンドは

valgrind --tool=callgrind ./heap

次に、入力します

callgrind_annotate --inclusive=yes callgrind.out.25434

出力:

`--------------------------------------------------------------------------------

Profile data file 'callgrind.out.25434' (creator: callgrind-3.6.0)

`--------------------------------------------------------------------------------

I1 cache:
D1 cache:
LL cache:
Timerange: Basic block 0 - 361578
Trigger: Program termination
Profiled target:  ./heap (PID 25434, part 1)
Events recorded:  Ir
Events shown:     Ir
Event sort order: Ir
Thresholds:       99
Include dirs:
User annotated:
Auto-annotation:  off

`--------------------------------------------------------------------------------

       Ir
`--------------------------------------------------------------------------------

2,552,558  PROGRAM TOTALS

`--------------------------------------------------------------------------------

       Ir  file:function

`--------------------------------------------------------------------------------

2,552,558  ???:0x00000810 [/lib/ld-2.7.so]

2,515,793  ???:0x00000a60 [/lib/ld-2.7.so]

2,515,219  ???:0x00015270 [/lib/ld-2.7.so]

2,514,780  ???:0x000021e0 [/lib/ld-2.7.so]

2,456,164  ???:0x0000b2f0 [/lib/ld-2.7.so]

2,256,719  ???:0x00009e40 [/lib/ld-2.7.so]

1,702,371  ???:0x00009ac0 [/lib/ld-2.7.so]

  657,883  ???:0x000098e0 [/lib/ld-2.7.so]

  367,045  ???:0x00017040 [/lib/ld-2.7.so]

   33,170  ???:0x080483e0 [/home/test/heap]

   33,036  ???:0x0000ce60 [/lib/ld-2.7.so]

   31,347  ???:0x0000e850 [/lib/ld-2.7.so]

   30,706  ???:(below main) [/lib/libc-2.7.so]

   30,071  ???:0x00008570 [/lib/ld-2.7.so]

   27,954  ???:0x0000f500 [/lib/ld-2.7.so]

   27,758  ???:0x0000ca30 [/lib/ld-2.7.so]

   21,366  ???:0x0001767b [/lib/ld-2.7.so]
4

1 に答える 1

5

main()、コール グラフの一番上の関数ではありません。glibc には_start関数があり、これを呼び出しmain()てから戻り値を取得しmainます。また、(動的にリンクされたプログラム = ほとんどすべて) 動的リンカー (ランタイム) としても知られる ELF インタープリターがあります: /lib/ld-linux.so (この名前は Linux で使用され、他の Unix では /lib のようなものです) /ld.so)。リンカーは、アプリケーションに必要なすべての動的ライブラリをロードして初期化します。の前にOSによって呼び出されます_start

の前に何が行われmainますか? ライブラリの読み込み (ライブラリ ファイルを開き、そのヘッダーを解析し、mmap し、メモリ内の新しい場所にコードを採用する = 再配置処理)、およびそれらの初期化 (動的および静的にリンクされたライブラリの両方でこれが必要です。glibc=libc もライブラリであることに注意してください) . __attribute__((constructor))各ライブラリには、ライブラリ (またはグローバル オブジェクトの自明でないコンストラクタ) のロード直後に開始されるコードが含まれる場合があります。また、glibc はいくつかの関数を main の後に実行するように登録することができ (例えばatexit(); main が正常に戻った場合、それらは _start によって呼び出されます)、ライブラリにはグローバル オブジェクトのデストラクタ関数が含まれる場合があります。

プログラムがスレッドを使用する場合、スレッドの最上位関数はメインではありません (各スレッドはスタックを分離でき、関数呼び出しのチェーンはスレッド 0 のスタックに格納されます) 1nmain

あなたの例では /lib/ld-*.so が表示されており、これは動的リンカーです。アプリケーションの実行が短すぎて正しくプロファイリングできず、多数の動的ライブラリを使用しているようです。

于 2011-12-04T04:47:38.027 に答える