Oracle® Developer Studio 12.5: パフォーマンスアナライザ

印刷ビューの終了

更新: 2016 年 6 月
 
 

コレクタが収集するデータ

コレクタは、次のいくつかの方法を使用して、さまざまな種類のデータを収集します。

  • プロファイリングデータの収集は、一定の間隔でプロファイルイベントを記録することによって行います。間隔は、システム時間を使用して取得した時間間隔、または特定のタイプのハードウェアイベントの数です。指定の間隔に達すると、シグナルがシステムに送られ、次の機会にデータが記録されます。

  • トレースデータは、さまざまなシステム関数やライブラリ関数の呼び出しをインターセプトし、その呼び出しに関するデータを記録できるように、それらの関数にラッパー関数で割り込むことによって収集されます。

  • 標本データの収集は、さまざまなシステムルーチンを呼び出して情報を取得することによって行います。

  • 関数と命令のカウントデータは、実行可能ファイルおよび共有オブジェクトを組み込むことにより、実行可能ファイルに対して収集されます。また、動的に開かれているか、計測され、その実行可能ファイルに静的にリンクしているすべての共有オブジェクトに対して収集されます。各関数または基本ブロックが実行された回数が記録されます。

  • スレッド解析データは、スレッドアナライザをサポートするために収集されます。

プロファイルデータとトレースデータの両方が特定のイベントに関する情報を含んでおり、いずれのデータの種類もパフォーマンスメトリックに変換されます。標本データはメトリックに変換されませんが、プログラムの実行を複数のタイムセグメントに分割するために使用できるマーカーを提供します。標本データは、タイムセグメントにおけるプログラム実行の概要を示します。

    それぞれのプロファイルイベントやトレースイベントで収集されたデータパケットには、次の情報が含まれます。

  • データ識別用のヘッダー。

  • 高分解能のタイムスタンプ。

  • スレッド ID。

  • プロセッサ (CPU) ID (オペレーティングシステムから提供できる場合)。

  • 呼び出しスタックのコピー。Java プログラムの場合、マシン呼び出しスタックと Java 呼び出しスタックの 2 つの呼び出しスタックが記録されます。

  • OpenMP プログラムの場合、現在の並行領域の識別子と、OpenMP の状態も収集されます。

スレッドと軽量プロセスについての詳細は、パフォーマンスアナライザとそのデータについてを参照してください。

こうした共通の情報のほかに、各イベントに固有のデータパケットには、データの種類に固有の情報が含まれます。

クロックプロファイリングデータ

クロックプロファイリング時に収集されるデータは、オペレーティングシステムが提供する情報によって異なります。

Oracle Solaris でのクロックプロファイリング

Oracle Solaris でのクロックプロファイリングでは、 各スレッドの状態が定期的な時間間隔で格納されます。この時間間隔は、 プロファイリング 間隔と呼ばれます。 収集されるデータは、プロファイリング間隔の分解能を使用して、それぞれの状態で経過した時間に変換されます。

デフォルトのプロファイル間隔は、約 10 ミリ秒 (10 ms) です。約 1 ms の高分解能のプロファイリング間隔と約 100 ms の低分解能のプロファイリング間隔を指定できます。オペレーティングシステムで許可されている場合は、カスタム間隔を指定することもできます。ほかの引数を指定せずに collect -h コマンドを実行して、システム上で許容可能な範囲と分解能を出力します。

次の表に、実験にクロックプロファイリングデータが含まれる場合に、パフォーマンスアナライザと er_print が表示できるパフォーマンスメトリックを示します。すべてのスレッドからのメトリックが同時に追加されることに注意してください。

表 1  Oracle Solaris でのクロックプロファイリングからのタイミングメトリック
メトリック
定義
スレッド合計時間
スレッドがすべての状態で費やした時間の合計。
合計 CPU 時間
ユーザーモード、カーネルモード、またはトラップモードの CPU での実行に費やされたスレッド時間
ユーザー CPU 時間
ユーザーモードの CPU での実行に費やされたスレッド時間。
システム CPU 時間
カーネルモードの CPU での実行に費やされたスレッド時間。
トラップ CPU 時間
トラップモードの CPU での実行に費やされたスレッド時間。
ユーザーロック時間
同期ロックの待機に費やされたスレッド時間。
データページフォルト時間
データページの待機に費やされたスレッド時間。
テキストページフォルト時間
テキストページの待機に費やされたスレッド時間。
カーネルページフォルト時間
カーネルページの待機に費やされたスレッド時間。
停止時間
停止に費やされたスレッド時間。
CPU 待ち時間
CPU の待機に費やされたスレッド時間。
スリープ時間
スリープに費やされたスレッド時間

タイミングメトリックは、プログラムがいくつかのカテゴリで時間を費やした部分を示し、プログラムのパフォーマンス向上に役立てることができます。

  • ユーザー CPU 時間が大きいということは、その場所で、プログラムが仕事の大半を行なっていることを示します。この情報は、アルゴリズムを再設計することによって特に有益となる可能性があるプログラム部分を見つけるのに使用できます。

  • システム CPU 時間が大きいということは、プログラムがシステムルーチンに対する呼び出しで多くの時間を使用していることを示します。

  • CPU 待ち時間が大きいということは、使用可能な CPU 以上に実行可能なスレッドが多いか、ほかのプロセスが CPU を使用していることを示します。

  • ユーザーロック時間が大きいということは、要求対象のロックをスレッドが取得できないことを示します。

  • テキストページフォルト時間が大きいということは、リンカーによって指定されたコードが、多数の呼び出しまたは分岐で新しいページの読み込みが発生するようなメモリー上の配置になることを意味します。

  • データページフォルト時間が大きいということは、データへのアクセスによって新しいページの読み込みが発生していること示します。この問題は、プログラムのデータ構造またはアルゴリズムを変更することによって解決できます。

Linux でのクロックプロファイリング

Linux プラットフォームでは、クロックデータは合計 CPU 時間としてのみ表示できます。Linux CPU 時間は、ユーザー CPU 時間とシステム CPU 時間の合計です。

OpenMP プログラム対応のクロックプロファイリング

クロックプロファイリングが OpenMP プログラムで実行される場合は、マスタースレッド時間、OpenMP 作業、および OpenMP 待機という追加メトリックが提供されます。

  • Oracle Solaris では、マスタースレッド時間はマスタースレッドで費やされた合計時間であり、時計時間に対応します。このメトリックは Linux では使用できません。

  • Oracle Solaris では、OpenMP 作業は、作業が直列または並列に実行されている場合に累積されます。OpenMP 待機は、OpenMP ランタイムが同期化を待機している場合に蓄積し、待機が CPU 時間またはスリーピングを使用しているか、または作業が並列実行中であるがスレッドが CPU 上にスケジュールされていない場合に蓄積します。

  • Linux オペレーティングシステムでは、OpenMP 作業および OpenMP 待機は、プロセスがユーザーモードまたはシステムモードでアクティブである場合にのみ累積されます。OpenMP でビジーウェイトを行う必要があるものとして指定しないかぎり、Linux での OpenMP は有用ではありません。

OpenMP プログラムのデータは、3 つの表示モードのいずれかで表示できます。「ユーザー」モードでは、スレーブスレッドが実際にマスタースレッドから複製され、呼び出しスタックがマスタースレッドからのスレーブスレッドに対応しているかのように表示されます。OpenMP 実行時コード (libmtsk.so) から来た、呼び出しスタック内のフレームは抑制されます。「上級」ユーザーモードでは、マスタースレッドとスレーブスレッドが異なる方法で表示され、コンパイラで生成された明示的な関数が表示され、OpenMP 実行時コード (libmtsk.so) からのフレームは抑制されます。「マシン」モードでは、実際のネイティブなスタックが表示されます。

Oracle Solaris カーネルに対するクロックプロファイリング

er_kernel ユーティリティーは、Oracle Solaris カーネルに関するクロックベースのプロファイルデータを収集できます。コマンド行から直接 er_kernel ユーティリティーを実行するか、パフォーマンスアナライザの「ファイル」メニューから「カーネルのプロファイル」を選択すると、カーネルのプロファイリングを行えます。

er_kernel ユーティリティーはカーネルプロファイルデータを取り込み、そのデータをパフォーマンスアナライザの実験として、ユーザープログラム上で collect ユーティリティーによって作成された実験と同じ形式で記録します。この実験は、er_print ユーティリティーまたはパフォーマンスアナライザによって処理できます。 カーネル実験は、関数データ、呼び出し元-呼び出し先データ、命令レベルのデータ、およびタイムラインを示すことができますが、ほとんどの Oracle Solaris モジュールが行番号テーブルを保持していないため、ソース行データを示すことはできません。

er_kernel は、ユーザーが権限を保持している、その時点で実行中のプロセスでのユーザーレベルの実験も記録できます。このような実験は、collect が作成する実験に似ていますが、ユーザー CPU 時間とシステム CPU 時間に関するデータだけを含み、Java および OpenMP プロファイリングはサポートしません。

詳細は、カーネルプロファイリングを参照してください。

MPI プログラム対応のクロックプロファイリング

クロックプロファイリングデータは、Oracle Message Passing Toolkit (以前の Sun HPC ClusterTools) で実行される MPI 実験で収集できます。Oracle Message Passing Toolkit はバージョン 8.1 またはそれ以降である必要があります。

Oracle Message Passing Toolkit は、Oracle Solaris 11 リリースの一部として入手できます。システムにインストールされている場合は、/usr/openmpi にあります。まだ Oracle Solaris 11 システムにインストールされていない場合、システムにパッケージリポジトリが構成されていれば、コマンド pkg search openmpi を使用してこのパッケージを検索できます。Oracle Solaris 11 でのソフトウェアのインストールの詳細は、『Oracle Solaris 11 ソフトウェアパッケージの追加および更新』を参照してください。

    MPI 実験に関するクロックプロファイリングデータを収集するときに、次の 2 つの追加メトリックが表示されます。

  • MPI 作業: 要求やメッセージの処理など、プロセスが MPI ランタイム実行作業の内部にある場合に蓄積されます。

  • MPI 待機: プロセスが MPI ランタイムの内部にあり、イベント、バッファー、またはメッセージを待機している場合に蓄積されます。

Oracle Solaris では、MPI 作業は、作業が直列または並列に実行されている場合に累積されます。MPI 待機は、MPI ランタイムが同期化を待機している間に蓄積され、待機が CPU 時間またはスリーピングを使用しているか、または作業が並列実行中であるがスレッドは CPU 上にスケジュールされていない場合に蓄積します。

Linux では、MPI 作業および MPI 待機は、プロセスがユーザーモードまたはシステムモードでアクティブである場合にのみ累積されます。MPI がビジーウェイトを行う必要があるものとして指定しないかぎり、Linux での MPI 待機は有用ではありません。


注 -  ほかのバージョンの MPI がサポートされています。完全なリストを表示するには、引数なしで collect と入力します。

注 -  Linux で Oracle Message Passing Toolkit 8.2 または 8.2.1 を使用する場合、回避策が必要になる場合があります。バージョン 8.1 または 8.2.1c では、または Oracle Developer Studio コンパイラを使用している場合はすべてのバージョンで、回避策は必要ありません。

Oracle Message Passing Toolkit のバージョンは、/opt/SUNWhpc/HPC8.2.1 などのインストールパスで示されています。または、mpirun —V と入力して表示される次のような出力では、斜体の部分でバージョンが示されています。

mpirun (Open MPI) 1.3.4r22104-ct8.2.1-b09d-r70

アプリケーションを GNU または Intel コンパイラでコンパイルし、Oracle Message Passing Toolkit 8.2 または 8.2.1 を MPI 用に使用している場合、MPI の状態データを取得するには、Oracle Message Passing Toolkit の link コマンドで –WI および –-enable-new-dtags オプションを使用する必要があります。これらのオプションを使用すると実行可能ファイルで RPATH に加えて RUNPATH が定義され、MPI 状態ライブラリが LD_LIBRARY_PATH 環境変数で有効になります。


ハードウェアカウンタプロファイリングデータ

ハードウェアカウンタは、キャッシュミス、キャッシュストールサイクル、浮動小数点演算、分岐予測ミス、CPU サイクル、および実行対象命令といったイベントの追跡に使用されます。ハードウェアカウンタ プロファイリングでは、スレッドが実行されている CPU の指定されたハードウェアカウンタがオーバーフローしたときに、コレクタによってプロファイルパケットが記録されます。この場合、そのカウンタはリセットされ、カウントを続行します。プロファイルパケットには、オーバーフロー値とカウンタタイプが入っています。

さまざまなプロセッサチップファミリが、2 ~ 18 個の同時ハードウェアカウンタレジスタをサポートしています。コレクタは、複数のレジスタ上でデータを収集できます。レジスタごとに、オーバーフローをモニターするカウンタの種類を選択したり、カウンタの オーバーフロー値 を設定したりすることができます。ハードウェアカウンタには、任意のレジスタを使用できるものと、特定のレジスタしか使用できないものがあります。このことは、1 つの実験であらゆるハードウェアカウンタの組み合わせを選択できるわけではないことを意味します。

また、ハードウェアカウンタプロファイリングは、パフォーマンスアナライザおよび er_kernel ユーティリティーを使用してカーネルに対して実行することもできます。詳細は、カーネルプロファイリングを参照してください。

パフォーマンスアナライザは、ハードウェアカウンタプロファイリングデータをカウントメトリックに変換します。周期的にカウントするカウンタの場合、報告されたメトリックが時間に変換されます。周期的にカウントしないカウンタの場合、報告されるメトリックはイベントカウントです。複数の CPU を搭載したマシンの場合、メトリックの変換に使用されるクロック周波数が個々の CPU のクロック周波数の調和平均となります。プロセッサのタイプごとに専用のハードウェアカウンタセットがあり、またハードウェアカウンタの数が多いため、ハードウェアカウンタメトリックはここに記載していません。ハードウェアカウンタリストでは、どのような種類のハードウェアカウンタがあるかについて調べる方法を説明します。

「cycles」と「insts」の 2 つの特定のカウンタが収集される場合、「CPI」と「IPC」という 2 つのメトリックが使用可能になり、これらはそれぞれ「命令当たりのサイクル数」と「サイクル当たりの命令数」を意味します。これらは常に比率として表示され、時間、カウント、あるいはパーセントで示されません。CPI 値が高いか IPC 値が低ければ、マシン内でのコードの実行が非効率であることを示し、逆に CPI 値が低いか IPC 値が高ければ、パイプライン内で実行中のコードの効率がよいことを示します。

ハードウェアカウンタの用途の 1 つは、CPU に出入りする情報フローに伴う問題を診断することです。たとえば、キャッシュミス回数が多いということは、プログラムを再構成してデータまたはテキストの局所性を改善するか、キャッシュの再利用を増やすことによってプログラムのパフォーマンスを改善できることを意味します。

ハードウェアカウンタはほかのカウンタと関連する場合があります。たとえば、分岐予測ミスが発生すると、間違った命令が命令キャッシュにロードされるため、分岐予測ミスと命令キャッシュミスが関連付けられることがよくあります。これらは正しい命令に置き換える必要があります。置換により、命令キャッシュミス、命令トランスレーションルックアサイドバッファー (ITLB) ミス、またはページフォルトが発生する可能性があります。

多くのハードウェアカウンタでは、オーバーフローイベントを引き起こした命令のあとの 1 つ以上の命令でオーバーフローが発生することがよくあります。この状況は「スキッド」と呼ばれ、カウンタオーバーフロープロファイルの解釈を困難にすることがあります。パフォーマンスデータは、観測されたイベントを実際に引き起こした命令のあとに実行された命令に関連付けられます。スキッドする命令の数は、多くのチップおよびカウンタでは確定していませんが、一部では正確に決まっています (通常は 0 または 1)。

メモリー関連のカウンタの一部は、スキッドが確定しているため、メモリー領域プロファイリングに使用できます。ハードウェアカウンタリストで説明されているリストで、このようなカウンタは「precise load-store」というラベルで示されます。このようなカウンタに対しては、トリガー元の PC および EA を特定でき、メモリー領域とデータ領域のデータがデフォルトで取得されます。詳細は、データ領域プロファイリングとメモリー領域プロファイリングを参照してください。

ハードウェアカウンタリスト

ハードウェアカウンタはプロセッサ固有であるため、どのカウンタを利用できるかは、使用しているプロセッサによって異なります。 パフォーマンスツールには、よく使われると考えられるいくつかのカウンタの別名が用意されています。現在のマシン上でほかのどの引数も指定せずに collect -h を実行することによって、現在のマシン上でのプロファイリングのためのハードウェアカウンタ定義の最大数を確認したり、使用可能なハードウェアカウンタの完全なリストやデフォルトのカウンタセットを表示したりすることができます。

プロセッサとシステムがハードウェアカウンタプロファイリングをサポートしている場合、collect -h コマンドは、ハードウェアカウンタに関する情報を含む 2 つのリストを出力します。最初のリストには、一般的な名称に別名が設定されたハードウェアカウンタが含まれます。2 番目のリストには、raw ハードウェアカウンタが含まれます。パフォーマンスカウンタサブシステムにも collect コマンドにも特定システムのカウンタの名前がない場合、各リストは空になります。ただしほとんどの場合、カウンタは数値で指定できます。

次の例では、カウンタリストに含まれるエントリを示します。 別名が設定されたカウンタがリストの最初に表示され、続いて raw ハードウェアカウンタリストが表示されます。 この例の出力における各行は、印刷用の形式になっています。

    Aliases for most useful HW counters:

    alias      raw name                     type      units regs description

    cycles     Cycles_user                       CPU-cycles 0123 CPU Cycles
    insts      Instr_all                             events 0123 Instructions Executed
    c_stalls   Commit_0_cyc                      CPU-cycles 0123 Stall Cycles
    loads      Instr_ld       precise load-store     events 0123 Load Instructions
    stores     Instr_st       precise load-store     events 0123 Store Instructions
    dcm        DC_miss_commit precise load-store     events 0123 L1 D-cache Misses
...

Raw HW counters:

    name                                    type      units regs description

    Sel_pipe_drain_cyc                           CPU-cycles 0123 
    Sel_0_wait_cyc                               CPU-cycles 0123 
    Sel_0_ready_cyc                              CPU-cycles 0123 
...
別名が設定されたハードウェアカウンタリストの形式

別名が設定されたハードウェアカウンタリストでは、最初のフィールド (たとえば、cycles) は、collect コマンドの -h counter... 引数で使用できる別名を示します。この別名は、er_print コマンド内で使用する識別子でもあります。

2 番目のフィールドは、カウンタの生の名前を示します。たとえば、loadsInstr_ld の省略です

3 番目のフィールドはタイプ情報を示し、空の場合もあります (たとえば、precise load-store)。

    種類情報フィールド内の可能性のあるエントリには次のものがあります。

  • precise。メモリーベースのカウンタ割り込みが、既知の正確なスキッドを伴って発生し、メモリー領域プロファイリングに対してサポートされます。このようなカウンタに対しては、パフォーマンスアナライザはメモリー領域とデータ領域のデータを収集でき、デフォルトで収集を行います。詳細は、「メモリーオブジェクト」ビューの説明を参照してください。

  • loadstore、または load-store のいずれかである場合、そのカウンタはメモリーに関連したものです。

  • not-program-related である場合、カウンタはほかのプログラムによって開始されたイベント、たとえば CPU 対 CPU のキャッシュスヌープなどを取り込みます。プロファイリングにカウンタを使用すると、警告が生成され、プロファイリングで呼び出しスタックが記録されません。

4 番目のフィールドは、カウントされている単位の種類を示します (たとえば、events)。

    単位は次のいずれかです。

  • CPU-cycles である場合は、そのカウンタを使用して時間ベースのメトリックを提供できます。そのようなカウンタについて報告されるメトリックは、デフォルトでは包括的時間および排他的時間へ変換されますが、イベントカウントとして表示することもできます。

  • events である場合、メトリックは包括的および排他的イベントカウントであり、時間へ変換できません。

5 番目のフィールドは、カウンタの使用可能なレジスタを示します。たとえば、0123 です。

6 番目のフィールドは、カウンタの簡単な説明を示します (たとえば、Load Instructions)。

raw ハードウェアカウンタリストの形式

raw ハードウェアカウンタリストに含まれる情報は、別名設定されたハードウェアカウンタリストに含まれる情報のサブセットです。raw ハードウェアカウンタリスト内の各行には、cputrack(1) で使用される内部カウンタ名、タイプ情報、CPU-cycles または events のどちらかのカウンタ単位、およびそのカウンタを使用できるレジスタ番号が含まれています。

カウンタがプログラムの実行に関連のないイベントを測定する場合、タイプ情報の最初のワードは not-program-related になります。そのようなカウンタの場合、プロファイリングで呼び出しスタックが記録されませんが、その代わりに、擬似関数 collector_not_program_related で使用された時間が示されます。スレッドと LWP ID は記録されますが、意味がありません。

raw カウンタのデフォルトのオーバーフロー値は 1000003 です。この値はほとんどの raw カウンタで最適でないため、raw カウンタを指定する際にオーバーフロー値を指定する必要があります。

同期待ちトレースデータ

マルチスレッドプログラムでは、別のスレッドで実行されるタスクの同期によって、プログラムの実行が遅延することがあります。たとえば、あるスレッドが、別のスレッドでロックされているデータへのアクセスを待機する必要が生じることがあります。 これらのイベントは同期遅延イベントと呼ばれ、Solaris または pthread のスレッド関数の呼び出しをトレースすることによって収集されます。 同期遅延イベントを収集して記録するプロセスを同期待ちトレースと言います。また、ロック待ちに費やされる時間を 同期待ち時間 と言います。

ただし、イベントが記録されるのは、その待ち時間がしきい値 (ミリ秒単位) を超えた場合だけです。しきい値 0 は、待ち時間に関係なく、あらゆる同期遅延イベントをトレースすることを意味します。 デフォルトでは、同期遅延なしにスレッドライブラリを呼び出す測定試験を実施して、しきい値を決定します。こうして決定された場合、しきい値は、それらの呼び出しの平均時間に任意の係数 (現在は 6) を乗算して得られた値です。この方法によって、待ち時間の原因が本当の遅延ではなく、呼び出しそのものにあるイベントが記録されないようになります。この結果として、同期イベント数がかなり過小評価される可能性がありますが、データ量は大幅に少なくなります。

Java プログラムの場合、同期トレースは、プロファイルされるプログラムでの Java メソッド呼び出し、ネイティブな同期呼び出し、またはその両方を対象にします。

同期待ちトレースデータは、次の表に示すメトリックに変換されます。

表 2  同期待ちトレースメトリック
メトリック
定義
同期遅延イベントカウント
待ち時間が所定のしきい値を超えたときの同期ルーチン呼び出し回数。
同期待ち時間
所定のしきい値を超えた総待ち時間。

この情報から、関数またはロードオブジェクトが頻繁にブロックされるかどうか、または同期ルーチンを呼び出したときの待ち時間が異常に長くなっているかどうかを調べることができます。同期待ち時間が大きいということは、スレッド間の競合が発生していることを示します。競合は、アルゴリズムの変更、具体的には、ロックする必要があるデータだけがスレッドごとにロックされるように、ロックを構成し直すことで減らすことができます。

ヒープトレース (メモリー割り当て) データ

正しく管理されていないメモリー割り当て関数やメモリー割り当て解除関数を呼び出すと、データの使い方の効率が低下し、プログラムパフォーマンスが低下する可能性があります。ヒープトレースでは、C 標準ライブラリメモリー割り当て関数 mallocreallocvallocmemalign、および割り当て解除関数 free で割り込み処理を行うことによって、コレクタはメモリーの割り当てと割り当て解除の要求をトレースします。mmap の呼び出しはメモリー割り当てとして扱われ、これによって Java メモリー割り当てのヒープトレースイベントを記録することが可能になります。Fortran 関数 allocate および deallocate は C 標準ライブラリ関数を呼び出すため、これらのルーチンは間接的にトレースされます。

Java プログラムのヒーププロファイリングはサポートされません。

ヒープトレースデータは、次のメトリックに変換されます。

表 3  メモリー割り当て (ヒープトレース) メトリック
メトリック
定義
割り当て
メモリー割り当て関数の呼び出し回数
割り当てバイト数
メモリー割り当て関数の呼び出しごとに割り当てられるバイト数の合計
リーク
対応するメモリー割り当て解除関数が存在しなかったメモリー割り当て関数の呼び出し回数
リークバイト数
割り当てられたが割り当て解除されなかったバイト数

ヒープトレースデータの収集は、プログラム内のメモリーリークを特定したり、メモリーの割り当てが不十分な場所を見つける上で役立ちます。

フィルタが適用された「リーク」ビューが表示された場合、そのリークはフィルタ基準で行われたメモリー割り当てに対するリークであり、常に割り当て解除されません。リークは、フィルタリング基準では割り当て解除されない割り当てに制限されません。

ここでのメモリーリークは、動的に割り当てられたが解放されることのないメモリーブロックと定義されます。そのメモリーブロックへのポインタがプロセスのアドレス空間に存在するかどうかは関係ありません。(ほかのツールでは、解放されていない割り当て済みメモリーブロックを指すポインタがプロセスのアドレス空間に存在しなくなった場合をリークと定義することがあります。)

I/O トレースデータ

I/O データ収集は、読み取りや書き込みを含む入力/出力システムコールをトレースします。呼び出しの時間を測定し、ファイルおよび記述子を追跡し、転送されたデータ量を測定します。I/O メトリックを使用すると、転送バイト数が多く、スレッド合計時間が長いファイル、ファイルハンドル、および呼び出しスタックを識別できます。

表 4  I/O トレースメトリック
メトリック
定義
読み取りバイト数
読み取り関数の各呼び出しで読み取られたバイト数の合計。
書き込みバイト数
書き込み関数の各呼び出しで書き込まれたバイト数の合計。
読み取り数
読み取り呼び出しが行われた回数。
書き込み数
書き込み呼び出しが行われた回数。
その他の I/O 数
その他の I/O 呼び出しが行われた回数
I/O エラー数
I/O 呼び出し中に発生したエラーの数
読み取り時間
データの読み取りにかかった秒数
書き込み時間
データの書き込みにかかった秒数
その他の I/O 時間
その他の I/O 呼び出しの実行にかかった秒数
I/O エラー時間
I/O エラーに費やされた秒数

標本データ

大域データは、コレクタによって標本パケットと呼ばれるパケット単位で記録されます。各パケットには、ヘッダー、タイムスタンプ、ページフォルトや I/O データなどのカーネルからの実行統計情報、コンテキストスイッチ、および各種のページの常駐性 (ワーキングセットおよびページング) 統計情報が含まれます。標本パケットに記録されるデータはプログラムに対して大域的であり、パフォーマンスメトリックスには変換されません。標本パケットを記録するプロセスを標本収集と言います。

    標本パケットは、次の状況で記録されます。

  • dbx でのデバッグ中に、プログラムが何らかの理由により停止したとき (ブレークポイントで停止するようにオプションが設定されている場合にブレークポイントに到達した場合など)。

  • 標本収集の間隔の終了時 (定期的な標本収集を選択している場合)。 標本収集の間隔は整数値 (秒単位) で指定します。デフォルト値は 1 秒です。

  • dbx collector sample record コマンドを使用し、標本を手動で記録したとき。

  • このルーチンに対する呼び出しがコードに含まれている場合に collector_sample を呼び出したとき (libcollector ライブラリを使用したデータ収集のプログラム制御を参照)。

  • collect コマンドで -l オプションが使用されている場合に指定した信号が送信されたとき (collect(1) のマニュアルページを参照)。

  • 収集が開始および終了したとき。

  • dbx collector pause コマンドで収集を一時停止したとき (一時停止の直前)、および dbx collector resume コマンドで収集を再開したとき (再開の直後)。

  • 派生プロセスが作成される前後。

パフォーマンスツールは、標本パケットに記録されたデータを使用して、期間別に分類します。この分類されたデータを標本と呼びます。特定の標本セットを選択することによってイベントに固有のデータをフィルタできるので、特定の期間に関する情報だけを表示させることができます。各標本の大域データを表示することもできます。

パフォーマンスツールは、標本ポイントのさまざまな種類を区別しません。標本ポイントを解析に利用するには、1 種類のポイントだけを記録対象として選択してください。特に、プログラム構造や実行シーケンスに関する標本ポイントを記録する場合は、定期的な標本収集を無効にし、dbx がプロセスを停止したとき、collect コマンドによってデータ記録中のプロセスにシグナルが送られたとき、あるいはコレクタ API 関数が呼び出されたときのいずれかの状況で記録された標本を使用します。

MPI トレースデータ

コレクタは、Message Passing Interface (MPI) ライブラリの呼び出しの際のデータを収集できます。

MPI トレースは、オープンソースの VampirTrace 5.5.3 リリースを使用して実装されます。これは次の VampirTrace 環境変数を認識します。

VT_STACKS
呼び出しスタックをデータに記録するかどうかを制御します。デフォルトの設定は 1 です。VT_STACKS0 に設定すると、呼び出しスタックが無効になります。
VT_BUFFER_SIZE
MPI API トレースコレクタの内部バッファーのサイズを制御します。デフォルト値は 64M (64M バイト) です。
VT_MAX_FLUSHES
MPI トレースの終了前に行うバッファーのフラッシュ回数を制御します。デフォルト値は 0 です。この場合、バッファーがいっぱいになるとディスクにフラッシュされます。VT_MAX_FLUSHES を正数に設定すると、バッファーがフラッシュされる回数が制限されます。
VT_VERBOSE
さまざまなエラーメッセージやステータスメッセージをオンにします。デフォルト値は 1 で、重大なエラーメッセージやステータスメッセージをオンにします。問題が生じる場合は、この変数を 2 に設定してください。

これらの変数については、Technische Universität Dresden Web サイトにある『Vampirtrace User Manual』を参照してください。

バッファーの制限に達したあとに発生する MPI イベントはトレースファイルに書き込まれないため、トレースが不完全になります。

この制限を撤廃してアプリケーションのトレースを完全なものにするには、VT_MAX_FLUSHES 環境変数を 0 に設定します。この設定を行うと、MPI API トレースコレクタは、バッファーがいっぱいになるたびにバッファーをディスクにフラッシュします。

バッファーのサイズを変更するには、VT_BUFFER_SIZE 環境変数を設定します。この変数の最適値は、トレース対象のアプリケーションによって異なります。小さな値を設定すると、アプリケーションに使用できるメモリーは増えますが、MPI API トレースコレクタによるバッファーのフラッシュが頻繁に行われるようになります。このようなバッファーのフラッシュによって、アプリケーションの動作が大幅に変化する可能性があります。その一方、大きな値 (2G など) を設定すると、MPI API トレースコントローラによるバッファーのフラッシュは最小限に抑えられますが、アプリケーションに使用できるメモリーは少なくなります。バッファーやアプリケーションデータを保持するために十分なメモリーを利用できない場合、アプリケーションの一部がディスクにスワップされて、アプリケーションの動作が大幅に変化する可能性があります。

次のリストに、データが収集される関数を示します。

MPI_Abort
MPI_Accumulate
MPI_Address
MPI_Allgather
MPI_Allgatherv
MPI_Allreduce
MPI_Alltoall
MPI_Alltoallv
MPI_Alltoallw
MPI_Attr_delete
MPI_Attr_get
MPI_Attr_put
MPI_Barrier
MPI_Bcast
MPI_Bsend
MPI_Bsend-init
MPI_Buffer_attach
MPI_Buffer_detach
MPI_Cancel
MPI_Cart_coords
MPI_Cart_create
MPI_Cart_get
MPI_Cart_map
MPI_Cart_rank
MPI_Cart_shift
MPI_Cart_sub
MPI_Cartdim_get
MPI_Comm_compare
MPI_Comm_create
MPI_Comm_dup
MPI_Comm_free
MPI_Comm_group
MPI_Comm_rank
MPI_Comm_remote_group
MPI_Comm_remote_size
MPI_Comm_size
MPI_Comm_split
MPI_Comm_test_inter
MPI_Dims_create
MPI_Errhandler_create
MPI_Errhandler_free
MPI_Errhandler_get
MPI_Errhandler_set
MPI_Error_class
MPI_Error_string
MPI_File_close
MPI_File_delete
MPI_File_get_amode
MPI_File_get_atomicity
MPI_File_get_byte_offset
MPI_File_get_group
MPI_File_get_info
MPI_File_get_position
MPI_File_get_position_shared
MPI_File_get_size
MPI_File_get_type_extent
MPI_File_get_view
MPI_File_iread
MPI_File_iread_at
MPI_File_iread_shared
MPI_File_iwrite
MPI_File_iwrite_at
MPI_File_iwrite_shared
MPI_File_open
MPI_File_preallocate
MPI_File_read
MPI_File_read_all
MPI_File_read_all_begin
MPI_File_read_all_end
MPI_File_read_at
MPI_File_read_at_all
MPI_File_read_at_all_begin
MPI_File_read_at_all_end
MPI_File_read_ordered
MPI_File_read_ordered_begin
MPI_File_read_ordered_end
MPI_File_read_shared
MPI_File_seek
MPI_File_seek_shared
MPI_File_set_atomicity
MPI_File_set_info
MPI_File_set_size
MPI_File_set_view
MPI_File_sync
MPI_File_write
MPI_File_write_all
MPI_File_write_all_begin
MPI_File_write_all_end
MPI_File_write_at
MPI_File_write_at_all
MPI_File_write_at_all_begin
MPI_File_write_at_all_end
MPI_File_write_ordered
MPI_File_write_ordered_begin
MPI_File_write_ordered_end
MPI_File_write_shared
MPI_Finalize
MPI_Gather
MPI_Gatherv
MPI_Get
MPI_Get_count
MPI_Get_elements
MPI_Get_processor_name
MPI_Get_version
MPI_Graph_create
MPI_Graph_get
MPI_Graph_map
MPI_Graph_neighbors
MPI_Graph_neighbors_count
MPI_Graphdims_get
MPI_Group_compare
MPI_Group_difference
MPI_Group_excl
MPI_Group_free
MPI_Group_incl
MPI_Group_intersection
MPI_Group_rank
MPI_Group_size
MPI_Group_translate_ranks
MPI_Group_union
MPI_Ibsend
MPI_Init
MPI_Init_thread
MPI_Intercomm_create
MPI_Intercomm_merge
MPI_Irecv
MPI_Irsend
MPI_Isend
MPI_Issend
MPI_Keyval_create
MPI_Keyval_free
MPI_Op_create
MPI_Op_free
MPI_Pack
MPI_Pack_size
MPI_Probe
MPI_Put
MPI_Recv
MPI_Recv_init
MPI_Reduce
MPI_Reduce_scatter
MPI_Request_free
MPI_Rsend
MPI_rsend_init
MPI_Scan
MPI_Scatter
MPI_Scatterv
MPI_Send
MPI_Send_init
MPI_Sendrecv
MPI_Sendrecv_replace
MPI_Ssend
MPI_Ssend_init
MPI_Start
MPI_Startall
MPI_Test
MPI_Test_cancelled
MPI_Testall
MPI_Testany
MPI_Testsome
MPI_Topo_test
MPI_Type_commit
MPI_Type_contiguous
MPI_Type_extent
MPI_Type_free
MPI_Type_hindexed
MPI_Type_hvector
MPI_Type_indexed
MPI_Type_lb
MPI_Type_size
MPI_Type_struct
MPI_Type_ub
MPI_Type_vector
MPI_Unpack
MPI_Wait
MPI_Waitall
MPI_Waitany
MPI_Waitsome
MPI_Win_complete
MPI_Win_create
MPI_Win_fence
MPI_Win_free
MPI_Win_lock
MPI_Win_post
MPI_Win_start
MPI_Win_test
MPI_Win_unlock

MPI トレースデータは、次のメトリックに変換されます。

表 5  MPI トレースメトリック
メトリック
定義
MPI 送信
開始された MPI ポイントツーポイント送信数
MPI 送信バイト数
MPI で送信されるバイト数
MPI 受信
完了した MPI ポイントツーポイント受信数
MPI 受信バイト数
MPI で受信されるバイト数
MPI 時間
MPI 関数へのすべての呼び出しにかかった時間
その他の MPI イベント
2 点間のメッセージの送受信を行わない MPI 関数の呼び出しの数

MPI 時間は、MPI 関数で費やされたスレッド合計時間です。MPI 状態の時間も収集される場合、MPI_Init および MPI_Finalize 以外のすべての MPI 関数については、MPI 作業時間と MPI 待機時間の合計が MPI 作業時間にほぼ等しくなるはずです。Linux では、MPI 待ちおよび MPI ワークがユーザーとシステムの CPU 時間に基づいているのに対して、MPI 時間は実際の時間に基づいているため、これらの数値は一致しません。

MPI のバイトおよびメッセージカウントは、現在、ポイントツーポイントメッセージについてのみ収集されます。これらは集合通信関数については記録されません。MPI 受信バイト数は、すべてのメッセージで実際に受信したバイト数をカウントします。MPI 送信バイト数は、すべてのメッセージで実際に送信したバイト数をカウントします。MPI 送信数は送信したメッセージの数をカウントし、MPI 受信数は受信したメッセージの数をカウントします。

MPI トレースデータの収集は、MPI 呼び出しが原因となる可能性のある、MPI プログラム内のパフォーマンスの問題を抱えている場所を特定する上で役立ちます。パフォーマンスの問題となる可能性のある例としては、負荷分散、同期遅延、および通信のボトルネックがあります。