私の理解では、デフォルトで gprof は CPU 時間を考慮に入れています。実時間に基づいてプロファイルする方法はありますか?
私のプログラムは多くのディスク I/O を行うため、使用する CPU 時間は実際の実行時間のほんの一部にすぎません。ディスク I/O のどの部分が最も時間を消費しているかを知る必要があります。
google-perftoolsのプロファイラーを使用して実時間を測定できます。グーグルプロファイラーを壁掛けモードに切り替えるには、環境変数CPUPROFILE_REALTIME=1を設定します。
strace または cachegrind を使用して、コードを適切にプロファイリングできます。strace はシステム コールに費やされた時間の詳細を提供し、cachegrind はリソース使用率の詳細な分析を提供します。
-finstrument-functions
これは、gcc コンパイラのオプションを使用して行うことができます。これにより、任意の関数のエントリ/終了ポイントで呼び出されるカスタム関数が取得されます。関数コールバック (__cyg_profile_func_enter
および__cyg_profile_func_exit
) をいくつか提供するだけで済みます。
-finstrument-functions
詳細については、gcc マニュアルでオプションを検索してください。
Balau の技術ブログには、これがどのように機能するかのエンド ツー エンドの概要/例を提供する優れた投稿もあります: Trace and profile function calls with GCC
gprof を変更して壁時計のプロファイリングを行うのは非常に簡単です。置換するのは次の 8 文字のみです。
ITIMER_PROF -> ITIMER_REAL
SIGPROF -> SIGALRM
ファイルglibc/sysdeps/posix/profil.c
、 関数、および__profil
への呼び出しの近く(より正確にはand )setitimer
sigaction
__Setitimer
__sigaction
変更後、SIGALRM を使用するすべてのプログラムは壊れ、ブロッキング syscall 再起動コードを持たないプログラムは、間違った結果をもたらす可能性があります。
また、glibc バイナリの int 値を直接変更することもできます (システム全体libc.so
でこれを行わないでください。別のコピーを作成し、LD_LIBRARY_PATH を使用してプログラムに渡してください)。
バイナリ パッチの場合、ITIMER_PROF は 2 です。ITIMER_REAL は 0 です。SIGPROF は 27 (0x1b) です。SIGALRM は 14 (0x0e) です。profil
glibc の関数では、各定数に対して 2 つの場所があります。
もう 1 つの方法は、実行時に setitimer および sigaction 関数の引数を変更する ptrace-debugger を作成することです。