web-dev-qa-db-ja.com

gccの-pgフラグはどのように機能しますか?

gccを使用してCコードをコンパイルするときに-pg(または-p)フラグがどのように機能するかを理解しようとしています。

公式のgccドキュメント 状態のみ

-pg
分析プログラムgprofに適したプロファイル情報を書き込むための追加コードを生成します。このオプションは、データが必要なソースファイルをコンパイルするときに使用する必要があります。また、リンクするときにも使用する必要があります。

私はプロファイラーについて小さな調査を行っているので、これは本当に興味があります-仕事に最適なツールを選択しようとしています。

23
Trevor

-pgでコンパイルすると、コードがインストルメント化され、gprofが詳細情報を報告します。 gprofのマニュアル、9.1プロファイリングの実装 を参照してください。

プロファイリングは、プログラム内のすべての関数のコンパイル方法を変更することで機能します。これにより、関数が呼び出されたときに、呼び出し元に関する情報が隠されます。これから、プロファイラーはどの関数がそれを呼び出したかを把握し、それが呼び出された回数を数えることができます。この変更は、プログラムが-pgオプションを使用してコンパイルされるときにコンパイラーによって行われます。これにより、すべての関数がmcount(または_mcount、または__mcountに応じて)を呼び出します。 OSとコンパイラ)を最初の操作の1つとして。

プロファイリングライブラリに含まれているmcountルーチンは、その親ルーチン(子)とその親の親の両方をメモリ内のコールグラフテーブルに記録する役割を果たします。これは通常、スタックフレームを調べて、子のアドレスと元の親の戻りアドレスの両方を見つけることによって行われます。これは非常にマシンに依存する操作であるため、mcount自体は通常、必要な情報を抽出し、2つの引数を指定して__mcount_internal(通常のC関数)を呼び出す短いアセンブリ言語スタブルーチンです。 frompcおよびselfpc__mcount_internalは、frompcselfpc、およびこれらの各コールアークがトラバースされた回数を記録するメモリ内コールグラフを維持する責任があります。

.。

このようなインストルメンテーションプロファイラーを使用すると、インストルメンテーションをプロファイリングせずにリリースでコンパイルするのと同じコードをプロファイリングすることに注意してください。インストルメンテーションコード自体に関連するオーバーヘッドがあります。また、インストルメンテーションコードは、命令とデータキャッシュの使用法を変更する場合があります。

インストルメンテーションプロファイラーとは異なり、 Intel VTune のようなサンプリングプロファイラーは、オペレーティングシステムの割り込みを使用して、ターゲットプログラムのプログラムカウンターを定期的に確認することにより、インストルメントされていないコードで機能します。また、特別なCPUレジスタにクエリを実行して、何が起こっているのかをさらに詳しく知ることもできます。

参照 プロファイラーインストルメンテーション対サンプリング

20
Gregory Pakosz

このリンク gprofがどのように機能するかについて簡単に説明します。

このリンク それについての広範な批評を与えます。 (アーカイブされた質問に対する私の答えを確認してください。)

6
Mike Dunlavey

このソースから: https://elinux.org/images/0/0c/Bird-LS-2009-Measuring-function-duration-with-ftrace.pdf

「インストルメンテーションには、明示的に宣言されたトレースポイントと暗黙的なトレースポイントの2つの主要な形式があります。明示的なトレースポイントは、トレースポイントの場所を指定する開発者定義の宣言と、特定のトレースサイトで収集する必要があるデータに関する追加情報で構成されます。暗黙的なトレースポイントが配置されます。コンパイラフラグまたは開発者が一般的に使用するマクロを再定義することにより、コンパイラによって自動的にコードに組み込まれます。

関数を暗黙的にインストルメント化するために、カーネルが関数トレースをサポートするように構成されている場合、カーネルビルドシステムはコンパイラで使用されるフラグに-pgを追加します。これにより、コンパイラは各関数のプロローグにコードを追加し、mcountと呼ばれる特別なアセンブリルーチンを呼び出します。このコンパイラオプションは、プロファイリングとトレースの目的で使用することを特に目的としています。 「」

0
laycat