Sun Studio 12: パフォーマンスアナライザ

プログラム構造へのメトリックの対応付け

メトリックは、イベント固有のデータとともに記録される呼び出しスタックを使用して、プログラムの命令に対応付けられます。情報を利用できる場合には、あらゆる命令がそれぞれ 1 つのソースコード行にマップされ、その命令に割り当てられたメトリックも同じソースコード行に対応付けられます。この仕組みについての詳細は、第 7 章「パフォーマンスアナライザとそのデータの内容」を参照してください。

メトリックは、ソースコードと命令のほかに、より上位のオブジェクト (関数とロードオブジェクト) にも対応付けられます。呼び出しスタックには、プロファイルが取られたときに記録された命令アドレスに達するまでに行われた、一連の関数呼び出しに関する情報が含まれます。パフォーマンスアナライザは、この呼び出しスタックを使用し、プログラム内の各関数のメトリックを計算します。こうして得られたメトリックを関数レベルのメトリックといいます。

関数レベルのメトリック: 排他的、包括的、属性

パフォーマンスアナライザが計算する関数レベルのメトリックには、排他的メトリック、包括的メトリック、および属性メトリックの 3 種類があります。

呼び出しスタックの一番下にのみ現れる関数 (リーフ関数) では、その関数の排他的および包括的メトリックは同じになります。

排他的および包括的メトリックは、ロードオブジェクトについても計算されます。ロードオブジェクトの排他的メトリックは、そのロードオブジェクト内の全関数の関数レベルのメトリックを集計することによって計算されるメトリックです。ロードオブジェクトの包括的メトリックは、関数に対するのと同じ方法で計算されるメトリックです。

関数の排他的および包括的メトリックは、その関数を通るすべての記録経路に関する情報を提供します。属性メトリックは、関数を通る特定の経路に関する情報を提供します。その情報は、どれだけのメトリックが特定の関数呼び出しが原因で発生したかを示します。呼び出しに関わる 2 つの関数を、呼び出し元および呼び出し先と呼びます。呼び出しツリーにおいて、それぞれの関数の属性メトリックは次の意味を持ちます。

メトリック間の関係は、次の等式で表すことができます。

メトリック間の関係を示す等式

呼び出し元または呼び出し先の属性メトリックと包括的メトリックを比較すると、さらに情報が得られます。

プログラムのパフォーマンス改善が可能な場所を見つける方法には、次のものがあります。

属性メトリックの意味: 例

図 2–1 は、排他的、包括的、属性メトリックを完全な呼び出しツリーで表しています。ここでは、中央の関数の関数 C に注目します。

プログラムの擬似コードは、図のあとに示されています。

図 2–1 排他的、包括的、属性メトリックを示す呼び出しツリー

排他的、包括的、属性メトリックを示す呼び出しツリー

Main 関数は、関数 A および関数 B を呼び出し、 Main 関数の包括的メトリックのうちの関数 A の 10 単位と関数 B の 20 単位の原因となっています。これらは、Main 関数の呼び出し先の属性メトリックです。その合計 (10+20) に Main 関数の排他的メトリックを加算すると、Main 関数の包括的メトリック (32) に等しくなります。

関数 A は関数 C の呼び出しにすべての時間を使用するため、排他的メトリックは 0 単位です。

関数 C は、関数 A および 関数 B の 2 つの関数によって呼び出され、関数 C の包括的メトリックのうちの関数 A の 10 単位と関数 B の 15 単位の原因になっています。これらは呼び出し元の属性メトリックです。その合計 (10+15) は、関数 C の包括的メトリック (25) に等しくなります。

呼び出し元の属性メトリックは、関数 A と B の包括的メトリックと排他的メトリックの差と等しくなります。これは、関数 A と B は関数 C のみを呼び出すことを意味します。実際、これらの関数がほかの関数を呼び出している場合がありますが、時間が短すぎて、実験に現れることはありません。

関数 C は、関数 E および関数 F の 2 つの関数を呼び出し、関数 C の包括的メトリックのうちの関数 E の 10 単位と関数 F の 10 単位の原因となっています。これらは、呼び出し先の属性メトリックです。その合計 (10+10) に関数 C の排他的メトリック (5) を加算すると、関数 C の包括的メトリック (25) に等しくなります。

関数 E と関数 F では、呼び出し先の属性メトリックと呼び出し元の包括的メトリックは等しくなります。これは、関数 E と関数 F が関数 C によってのみ呼び出されることを意味します。関数 E では、排他的メトリックと包括的メトリックが同じですが、関数 F では異なります。これは、関数 F はほかの関数 (関数 G) を呼び出しますが、関数 E はそうしないためです。

このプログラムの擬似コードを次に示します。

    main() {
       A();
       /2 単位の処理を行います。/
       B();
    }

    A() {
       C(10);
    }

    B() {
       C(7.5);
       /5 単位の処理を行います。/
       C(7.5);
    }

    C(arg) {
          /C 自体で 20 %、E の呼び出しに 40 %、F の呼び出しに 40 %
           を実行し、合計「arg」単位の処理を行います。/
    }

関数レベルのメトリックに再帰が及ぼす影響

直接または間接のどちらの場合も、再帰関数呼び出しがあると、メトリックの計算が複雑になります。パフォーマンスアナライザは、関数の呼び出しごとではなく、その関数全体のメトリックを表示します。このため、一連の再帰呼び出しのメトリックを 1 つのメトリックに要約する必要があります。この要約によって、呼び出しスタックの最後の関数 (リーフ関数) から計算される排他的メトリックが影響を受けることはありませんが、包括的および属性メトリックは影響を受けます。

包括的メトリックは、イベントのメトリックと呼び出しスタック内の関数の包括的メトリックを合計することによって計算されます。再帰呼び出しスタックにおいてメトリックが複数回カウントされないようにするには、イベントのメトリックが、同じ関数の包括的メトリックに複数回加算されないようにします。

属性メトリックは、包括的メトリックから計算されます。もっとも簡単な再帰では、再帰関数は、それ自身ともう 1 つの関数 (呼び出しを開始する関数) の 2 つの呼び出し元を持ちます。最後の呼び出しですべての動作を終えた場合、再帰関数の包括的メトリックの原因になるのは、その再帰関数であり、呼び出しを開始した関数ではありません。これは、再帰関数の上位にあるすべての呼び出しの包括的メトリックは、メトリックの複数回のカウントを回避するために、ゼロと見なされるためです。ただし、呼び出しを開始した関数は、再帰呼び出しであるために、呼び出し先としての再帰関数の包括的メトリックの一部の原因になります。