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

第 3 章 パフォーマンスデータの収集

パフォーマンス解析の第一段階は、データ収集です。この章では、データ収集のための準備、収集データの格納場所、データの収集方法、およびデータ収集の管理方法について説明します。データそのものの詳細については、第 2 章「パフォーマンスデータ」を参照してください。

この章では、次の内容について説明します。

プログラムのコンパイルとリンク

プログラムのコンパイル時には、ほとんどのオプションを使用してデータの収集および解析を行うことができますが、収集対象とパフォーマンスアナライザでの表示対象に影響するオプションがいくつかあります。プログラムのコンパイルとリンクを行う際に考慮すべき事柄について、このあとの各項で説明します。

ソースコード情報

注釈付き「ソース」と「逆アセンブリ」解析にソースコードを表示し、「行」解析にソース行を表示するには、-g コンパイラオプション (C++ でフロントエンドインライン化を有効にするには -g0) で対象のソースファイルをコンパイルして、デバッグシンボル情報を作成します。デバッグシンボル情報の形式は、-xdebugformat=(dwarf|stabs) で指定し、スタブと DWARF2 のいずれかとすることができます。デフォルトのデバッグ形式は dwarf です。

データ空間プロファイルを許可するコンパイルオブジェクトのデバッグ情報を準備するには、-xhwcprof -xdebugformat=dwarf と任意の最適化レベルを指定してコンパイルします。データ空間プロファイルは現時点では SPARC® プロセッサだけが対象です。現在は、最適化を行わないと、この機能は使用できません。「データオブジェクト」解析でプログラムデータオブジェクトを表示するには、-g (または C++ の場合は -g0) も追加して十分なシンボル情報を取得します。

DWARF 形式のデバッグ用シンボルで構築された実行可能ファイルやライブラリには、各成分オブジェクトファイルのデバッグシンボルのコピーが自動的に取り込まれます。スタブ形式のデバッグ用シンボルで構築された実行可能ファイルとライブラリにも、各成分オブジェクトファイルのデバッグシンボルのコピーが取り込まれます。ただし、それらの実行可能ファイルとライブラリが、各種オブジェクトファイル内と実行可能ファイル内にスタブシンボルを残す -xs オプションを使用してリンクされている必要があります。この情報の取り込みは、オブジェクトファイルを移動したり、削除したりする必要がある場合に特に有用です。すべてのデバッグ用シンボルが実行可能ファイルとライブラリ自体にあるので、実験とプログラム関連ファイルを別の場所に容易に移動できます。

静的リンク

プログラムをコンパイルするときに、-dn および -Bstatic コンパイラオプションを使用して動的リンクを無効にしないでください。 完全に静的にリンクされたプログラムのデータを収集しようとしても、コレクタからエラーメッセージが返され、データは収集されません。このエラーが発生する原因は、コレクタを実行したときに、コレクタライブラリが動的に読み込まれるためです。

システムライブラリを静的リンクしないでください。システムライブラリを静的リンクしてしまうと、トレースデータを何も収集できなくなることがあります。また、コレクタライブラリ libcollector.so へもリンクしないでください。

コンパイル時の最適化

何らかのレベルの最適化を有効にしてプログラムをコンパイルすると、コンパイラが実行順序を変更できるため、プログラム内の行の順序どおりにコードが実行されなくなります。この場合、パフォーマンスアナライザは、最適化されたコードについて収集された実験データを解析できますが、しばしば、逆アセンブリレベルでパフォーマンスアナライザが提供するデータを元のソースコード行に対応付けることが困難になります。また、コンパイラが末尾呼び出しの最適化を行う場合には、呼び出しシーケンスが予想とは異なっているように見えることがあります。詳細は、「末尾呼び出しの最適化」を参照してください。

Java プログラムのコンパイル

javac による Java プログラムのコンパイルに特別なアクションは不要です。

データ収集と解析のためのプログラムの準備

データ収集と解析の準備のためにプログラムに対して行う特別な作業はありません。次の処理のうち、いずれか 1 つでも行うプログラムの場合には、後述の該当する節を読んでください。

また、データ収集をプログラムから制御する場合も、該当する節を読んでください。

動的割り当てメモリーの利用

多くのプログラムは、次のような機能を使用して、動的に割り当てられたメモリーに依存しています。

初期値の設定としてメモリーの割り当て方法が明示的に規定されていないかぎり、プログラムが動的に割り当てられるメモリーの初期内容に依存しないように注意する必要があります。たとえば、malloc(3C) のマニュアルページにある callocmalloc の説明を比較してください。

動的に割り当てられるメモリーを使用するプログラムを単独で実行すると、正常に機能しているように見えることがありますが、パフォーマンスデータの収集を有効にした状態で実行すると、問題が起きることがあります。そのときの症状には、予期しない浮動小数点演算動作、セグメント例外、またはアプリケーション固有のエラーメッセージなどが含まれる場合があります。

こうした症状は、アプリケーションが単独で実行されたときには、初期化されていないメモリーの値が動作に影響ないものであっても、パフォーマンスデータの収集ツールとの組み合わせで実行されたときに別の値が設定されることによって、発生する場合があります。この場合は、パフォーマンスツールの問題ではありません。動的に割り当てられたメモリーの内容に依存するアプリケーションのどれにも、潜在的な問題があります。別途、明示的に規定されていないかぎり、オペレーティングシステムは、どのような内容であれ、動的に割り当てられたメモリー上の内容の提供を自由に行えます。現在のオペレーティングシステムが動的に割り当てられるメモリーに必ず特定の値を設定するようになっていたとしても、将来オペレーティングシステムのリリースが変わったとき、あるいはプログラムを別のオペレーティングシステムに移植した場合には、こうした潜在的な問題によって、予期しない動作が発生する可能性があります。

次のツールが、こうした潜在的な問題の発見に役立ちます。

システムライブラリの使用

コレクタは、さまざまなシステムライブラリの関数に割り込み、トレースデータを収集し、データ収集の完全性を確保します。コレクタがライブラリ関数の呼び出しに割り込む状況を次に示します。

次のような環境では、割り込みが成功しません。

コレクタが割り込み処理を行えなかった場合には、パフォーマンスデータが消去されたり無効になったりする可能性があります。

シグナルハンドラの使用

コレクタは、シグナルを 2 つ使用してプロファイルデータを収集します。全実験用の SIGPROF と、ハードウェアカウンタ実験専用の SIGEMT です。コレクタはこれらのシグナルのそれぞれを対象としてシグナルハンドラをインストールします。シグナルハンドラは自身のシグナルをインターセプトして処理しますが、ほかのシグナルは、インストールされているほかのシグナルハンドラに引き渡します。プログラムがこれらのシグナル用に独自のシグナルハンドラをインストールすると、コレクタは自分のシグナルハンドラをプライマリハンドラとして再インストールし、それによって完全なパフォーマンスデータが確保されます。

collect コマンドでは、ユーザー指定のシグナルを使用してデータ収集の一時停止と再開、および標本の記録を行えます。それらのシグナルはコレクタによって保護されませんが、ユーザーハンドラがインストールされている場合は、実験に警告が書き出されます。コレクタとアプリケーションによる指定シグナルの使用が互いに競合しないように、ユーザーが責任を持って確認する必要があります。

コレクタによってインストールされたシグナルハンドラは、システムコールがシグナル配信のために中断されないようにするためのフラグを設定します。この方法では、プログラムのシグナルハンドラがシステムコールの中断を許可するようにフラグを設定した場合に、プログラムの動作が変わる可能性があります。動作が変化する重要な例としては、非同期キャンセル処理に SIGPROF を使用し、システムコールの中断を行う非同期入出力ライブラリ libaio.so があります。コレクタライブラリ libcollector.so がインストールされている場合は必ず、キャンセルシグナルの到着が非同期入出力操作の取り消しに間に合わないほど遅れます。

コレクタライブラリを事前読み込みしないままプロセスに dbx を接続してパフォーマンスデータ収集を有効にし、そのあとでプログラムが自分のシグナルハンドラをインストールすると、コレクタは自分のシグナルハンドラを再インストールしません。この場合、プログラムのシグナルハンドラは、 パフォーマンスデータが失われないように、SIGPROFSIGEMT のシグナルが確実に渡されるようにする必要があります。プログラムのシグナルハンドラがシステムコールを中断した場合のプログラムの動作とプロファイルの動作は、コレクタライブラリが事前読み込みされた場合の動作と異なります。

setuid の使用

動的ローダーによって課される制約は、setuid(2) の使用とパフォーマンスデータの収集を困難にします。プログラムが setuid を呼び出すか setuid ファイルを実行する場合、コレクタは新しいユーザー ID に必要なアクセス権がないために、実験ファイルに書き込めない可能性が高くなります。

この問題は、プロセスが実行される可能性があるすべての UID または GID に書き込み権を与えるように umask を設定することで回避できます。ID には、実験の書き込み権が必要です。

データ収集のプログラム制御

プログラムからデータ収集を制御するには、コレクタ共有ライブラリ libcollector.so に入っている API 関数をプログラムで使用します。 これらの関数は C で記述されており、Fortran インタフェースも用意されています。ライブラリとともに提供されるヘッダーファイルに、C インタフェースと Fortran インタフェースの両方が定義されています。

API 関数は、次のように定義されます。


void collector_sample(char *name);
void collector_pause(void);
void collector_resume(void);
void collector_thread_pause(unsigned int t);
void collector_thread_resume(unsigned int t);
void collector_terminate_expt(void);

CollectorAPI クラスに、JavaTM プログラム用の類似の機能が用意されており、これについては、「Java インタフェース」で説明しています。

C/C++ インタフェース

C/C++ インタフェースにアクセスする方法は 2 通りあります。

Fortran インタフェース

Fortran API の libfcollector.h ファイルには、ライブラリに対する Fortran インタフェースが定義されています。このライブラリを使用するには、アプリケーションを -lcollectorAPI にリンクする必要があります。このライブラリには、下位互換性を維持するため、-lfcollector というもう 1 つの名前も用意されています。動的関数とスレッドによる呼び出しの一時停止と再開を除けば、Fortran API は C/C++ API と同じ機能を提供します。

Fortran の場合、API 関数を使用するには、次の文を挿入します。


include "libfcollector.h"

注 –

どんな言語を使用している場合も、プログラムを -lcollector とリンクしないでください。リンクした場合、コレクタが予期しない動作をすることがあります。


Java インタフェース

次の文を使用して、CollectorAPI クラスをインポートし、Java API にアクセスできます。ただし、アプリケーションは / installation_directory/lib/collector.jar (ここで、installation-directory は Sun Studio ソフトウェアがインストールされているディレクトリ) を指すクラスパスがある状態で呼び出される必要があります。


import com.sun.forte.st.collector.CollectorAPI;

Java CollectorAPI メソッドは、次のように定義されます。


CollectorAPI.sample(String name)
CollectorAPI.pause()
CollectorAPI.resume()
CollectorAPI.threadPause(Thread thread)
CollectorAPI.threadResume(Thread thread)
CollectorAPI.terminate()

Java API には、動的関数 API 以外の C および C++ API と同じ関数が含まれています。

C インクルードファイルの libcollector.h には、データが収集されていないときには実際の API 関数の呼び出しを迂回するマクロが入っています。この場合、関数は動的に読み込まれません。ただし、一部の環境ではうまく機能しないことがあるため、これらのマクロを使用するのは危険です。collectorAPI.h はマクロを使用していないため、このファイルを利用する方が安全です。このファイルでは、関数が直接参照されます。

Fortran API サブルーチンはパフォーマンスデータが収集されているときには C API 関数を呼び出し、そうでないときには復帰します。チェック処理のオーバーヘッドは非常に小さいので、プログラムのパフォーマンスにはあまり影響がないはずです。

パフォーマンスデータを収集するには、この章で後述するように、コレクタを使用してプログラムを実行する必要があります。API 関数への呼び出しを挿入することによって、データ収集が有効になることはありません。

マルチスレッドプログラムで API 関数を使用する場合には、これらの関数が 1 つのスレッドによってのみ呼び出されるようにする必要があります。collector_thread_pause() および collector_thread_resume() 以外は、API 関数が行うアクションの対象はプロセスであって、個々のスレッドではありません。各スレッドが API 関数を呼び出すと、記録されたデータが期待したものにならない可能性があります。たとえば、あるスレッドが collector_pause()collector_terminate_expt() を呼び出したときに、ほかのスレッドがまだプログラム内のそのポイントに達していない場合、すべてのスレッドについて収集が一時停止または停止され、この API 呼び出しの前にコードを実行していたスレッドのデータが失われる可能性があります。データ収集を個々のスレッドレベルで制御するには、collector_thread_pause() 関数と collector_thread_resume() 関数を使用します。これらの関数の使用方法として、1 つのマスタースレッドで、それ自体を含むすべてのスレッドのすべての呼び出しを行う方法と、各スレッドで自身のみの呼び出しを行う方法があります。その他の使用方法では、結果が予測できないものになる可能性があります。

C/C++、Fortran、および Java API 関数

ここでは、データ収集に関係する API 関数について説明します。

動的な関数とモジュール

使用している C または C++ プログラムが、コンパイル時にそのデータ空間に関数を動的に取り込む場合、動的関数やモジュールのデータをパフォーマンスアナライザで見るには、コレクタに情報を与える必要があります。この情報は、コレクタ API 関数の呼び出しによって渡されます。API 関数の定義は、次のとおりです。


void collector_func_load(char *name, char *alias,
    char *sourcename, void *vaddr, int size, int lntsize,
    Lineno *lntable);
void collector_func_unload(void *vaddr);

Java HotSpotTM 仮想マシンによってコンパイルされる Java メソッドには別のインタフェースが使用されるので、これらの API 関数を使用する必要はありません。Java インタフェースは、コンパイルされたメソッドの名前をコレクタに知らせます。Java コンパイル済みメソッドの関数データと注釈付き逆アセンブリのリストを見ることはできますが、注釈付きソースリストを見ることはできません。

ここでは、データ収集に関係する API 関数について説明します。

collector_func_load()

実験への記録のため、動的にコンパイルされた関数に関する情報をコレクタに渡します。パラメータリストを次の表に示します。

表 3–1 collector_func_load() のパラメータリスト

パラメータ 

定義 

name

パフォーマンスツールで使用する、動的にコンパイルされた関数の名前。実際の関数名でなくてもかまいません。この名前は関数の通常の命名規則に従っている必要はありませんが、空白文字や引用符は含めないようにします。 

alias

関数の説明に使用する任意の文字列。NULL を使用できます。この文字列が解釈の対象となることはありません。 空白文字を含めることができます。アナライザの「概要」タブに表示されます。何の関数であるか、またはなぜ関数が動的に構築されたかを示すために使用できます。

sourcename

関数の構築元であるソースファイルのパス。NULL を使用できます。このソースファイルは、注釈付きソースリストに使用されます。

vaddr

関数が読み込まれたアドレス。 

size

バイト数による関数のサイズ。 

lntsize

行番号テーブルのエントリの数を示すカウント。行番号情報がない場合には、ゼロとなります。 

lntable

lntsize エントリが入っているテーブル。各エントリは、整数対です。第 1 整数はオフセット、第 2 整数は行番号です。あるエントリのオフセットと次のエントリのオフセットとの間の命令はすべて、最初のエントリの行番号に対応します。オフセットは数字の昇順にする必要があります。 行番号の順序は任意です。lntableNULL である場合、関数のソースリストは利用できませんが、逆アセンブリリストは利用できます。

collector_func_unload()

アドレス vaddr にある動的関数が読み込み解除されたことをコレクタに通知します。

データ収集に関する制限事項

ここでは、ハードウェア、オペレーティングシステム、プログラムの実行方法、またはコレクタそのものによって課されるデータ収集の制限事項について説明します。

異なる種類のデータの同時収集に対する制限はありません。すなわち、どのようなデータの種類でも、ほかのデータの種類と同時に収集できます。

時間ベースのプロファイルに関する制限事項

プロファイル間隔の最小値とプロファイルに使用する時間の分解能は、特定のオペレーティング環境により異なります。最大値は 1 秒です。プロファイル間隔の値は、時間の分解能のもっとも近い倍数に切り捨てられます。最小値および最大値と時間の分解能を検索するには、引数を付けずに collect コマンドを入力します。

時間プロファイルによる実行時のひずみと実行時間の拡大

時間ベースのプロファイルでは、SIGPROF シグナルがターゲットに送られたときにデータが記録されます。それによってシグナルを処理するための実行時間の拡大が発生し、呼び出しスタックが展開されます。呼び出しスタックが深く、シグナルが頻繁なほど、実行時間の拡大は大きくなります。一定の範囲までは、時間ベースのプロファイルにより、ある程度の実行時間の拡大が生じますが、これはもっとも深いスタックで実行するプログラムの各部分の実行時間の拡大が大きくなることから生まれます。

可能な場合、デフォルト値は正確なミリ秒数でなく、システムクロックとの相関を回避するために、正確な数値と多少異なる値 (たとえば、10.007ms または 0.997ms など) に設定されます。システムクロックとの相関はデータのひずみをもたらす場合もあります。SPARC プラットフォームでは、同じ方法でカスタム値を設定してください (Linux プラットフォーム上では不可能)。

トレースデータの収集に関する制限事項

コレクタライブラリ libcollector.so が事前読み込みされていないかぎり、すでに稼働中のプログラムからはトレースデータを収集できません。詳細は、「動作中のプロセスからのトレースデータの収集」を参照してください。

トレースによる実行時のひずみと実行時間の拡大

データのトレースは、トレースされるイベント数に比例して実行時間を拡大させます。時間ベースのプロファイルを同時に行うと、イベントのトレースに起因する実行時間の拡大により、時間データにひずみが生じます。

ハードウェアカウンタオーバーフローのプロファイルに関する制限事項

ハードウェアカウンタオーバーフローのプロファイルには、次のような制限があります。

ハードウェアカウンタオーバーフローのプロファイルによる実行時のひずみと実行時間の拡大

ハードウェアカウンタのプロファイルでは、SIGEMT がターゲットへ送られたときにデータが記録されます。それによってシグナルを処理するための実行時間の拡大が発生し、呼び出しスタックが展開されます。時間ベースのプロファイルと違い、ハードウェアカウンタによっては、プログラムのさまざまな部分がその他の部分より高速にイベントを生成する場合があり、そのコード部分に実行時間の拡大が生じます。そのようなイベントを非常に高速に生成するプログラムの一部で大きなひずみが生じる場合があります。同様に、あるスレッドでは、ほかのスレッドと不均等にイベントが生成されるものがあります。

派生プロセスのデータ収集における制限事項

派生プロセスに関するデータを収集するには、いくつかの制限事項があります。

コレクタでの派生プロセスすべてについてデータを収集するには、次のいずれかのオプションとともに collect コマンドを使用する必要があります。

-F オプションの詳細については、「実験制御オプション」を参照してください。

Java プロファイルに関する制限事項

Java プログラムに関するデータは収集可能ですが、次の制限事項があります。

Java プログラミング言語で書かれたアプリケーションの実行時のひずみと実行時間の拡大

Java のプロファイリングでは、Java Virtual Machine Tools Interface (JVMTI) が使用され、実行のひずみと実行時間の拡大が発生する場合があります。

時間ベースのプロファイリングとハードウェアカウンタオーバーフローのプロファイルリングの場合、データ収集プロセスは JVM ソフトウェアへのさまざまな呼び出しを行い、プロファイリングイベントをシグナルハンドラ内で処理します。これらのルーチンのオーバーヘッドとディスクへの実験の書き込みコストにより、Java プログラムの実行時間の拡大が生じます。そのような実行時間の拡大は通常 10% より少なくなります。

同期トレースの場合は、データ収集でその他の JVMTI イベントを使用するので、アプリケーション内のモニター競合の量に比例して実行時間の拡大が発生します。

収集データの格納場所

プログラムの実行中に収集されたデータを「実験」といいます。実験は、1 つのディレクトリに格納される一連のファイルで構成されます。実験の名前は、ディレクトリの名前です。

コレクタは実験データを記録するばかりでなく、プログラムが使用したロードオブジェクトの独自のアーカイブも作成します。これらのアーカイブには、すべてのオブジェクトファイルとそのロードオブジェクト内のすべての関数のアドレス、サイズ、名前、ロードオブジェクトのアドレス、その最終変更日時を示すタイムスタンプが含まれます。

デフォルトでは、実験は現在のディレクトリに格納されます。このディレクトリがネットワーク接続されたファイルシステム上にある場合は、ローカルのファイルシステム上にあるときよりもデータの格納に長い時間がかかり、パフォーマンスデータにひずみが生じる可能性があります。可能であれば、常に、実験はローカルのファイルシステムに記録するようにしてください。コレクタを実行するときに、格納場所を指定することができます。

派生プロセスの実験は、親プロセスの実験の中に格納されます。

実験名

実験のデフォルト名は、test.1.er です。接尾辞 .er は必須です。この接尾辞のない名前を指定すると、エラーメッセージが表示され、名前は受け付けられません。

experiment .n.er という形式の名前を選択した場合 (ただし、n は正の整数)、コレクタは後続の実験の名前の中で、n を自動的に 1 ずつ増分します。たとえば、mytest.1.er の次は mytest.2.er となり、その次は mytest.3.er のように続きます。コレクタはまた、実験がすでに存在する場合も n を増分し、すでに実験名が使用されている場合は、使用されていない実験名が見つかるまで n の増分を繰り返します。実験が存在していても実験名に n が含まれていない場合、コレクタはエラーメッセージを出力します。

実験はグループにまとめることができます。グループは、デフォルト時に現在のディレクトリに格納される実験グループファイルにおいて定義されます。実験グループファイルは、1 行のヘッダー行のあとに 1 行につき 1 つの実験名が定義されているプレーンテキストファイルです。実験グループファイルのデフォルト名は、test.erg です。ファイル名の末尾が .erg でない場合はエラーとなり、ファイル名は受け付けられません。実験グループを作成すると、そのグループ名で実行したすべての実験がグループに追加されます。

次に示す行を最初に持つプレーンテキストファイルを作成すると、実験グループを手動で作成できます。


#analyzer experiment group

このあとの行に実験の名前を追加します。ファイルの名前の最後は、.erg でなければなりません。

collect ユーティリティーの -g 引数を使用して、実験グループを作成することもできます。

MPI プロセスごとに実験が 1 つ作成される MPI プログラムから収集された実験では、デフォルトの実験名が異なります。デフォルトの実験名は test.m.er で、m はそのプロセスの MPI ランクです。group.erg という実験グループを指定した場合、デフォルトの実験名は group.m.er です。実験名を指定した場合は、これらのデフォルトが置き換えられます。詳細は、「MPI プログラムからのデータの収集」を参照してください。

派生プロセスの実験は、次のとおり、その系統に基づいて命名されます。派生プロセスの実験名は、その親の実験名に下線、コード文字、数字を追加して作成されます。コード文字は、fork の場合は f、exec の場合は x、組み合わせの場合は c です。数字は、fork または exec のインデックスで、成功したかどうかには関係ありません。たとえば親プロセスの実験名が test.1.er の場合、3 回目の fork の呼び出しで作成された子プロセスの実験は test.1.er/_f3.er となります。この子プロセスが exec の呼び出しに成功した場合、新しい派生プロセスの実験名は test.1.er/_f3_x1.er となります。

実験の移動

別のコンピュータに実験を移動して解析する場合には、実験が記録されたオペレーティング環境に解析結果が依存することを念頭に置いてください。

アーカイブファイルには、関数レベルでメトリックを計算してタイムラインを表示するのに必要な情報がすべて入っています。ただし、注釈付きソースコードや注釈付き逆アセンブリコードを調べるには、実験の記録時に使用されたものと同じバージョンのロードオブジェクトやソースファイルにアクセスできる必要があります。

パフォーマンスアナライザはソースファイル、オブジェクトファイル、および実行可能ファイルを次の場所で順に検索し、正しいベース名のファイルが見つかると検索を停止します。

アナライザ GUI から、または setpath および addpath 指令を使って、検索順序を変更したり、ほかの検索ディレクトリを追加したりできます。

プログラムの正しい注釈付きソースコードと注釈付き逆アセンブリコードが確実に表示されるようにするには、ソースコード、オブジェクトファイル、および実行可能ファイルを実験にコピーしてから実験の移動やコピーを行います。オブジェクトファイルをコピーしたくない場合には、-xs を使用してプログラムをリンクし、ソース行とファイル位置に関する情報が実行可能ファイルに挿入されるようにします。collect コマンドの -A オプション、または dbx collector archive コマンドを使用して、実験にロードオブジェクトを自動的にコピーすることができます。

必要なディスク容量の概算

この節では、実験の記録に必要な空きディスク容量を概算するにあたってのガイドラインを示します。実験のサイズはデータパケットのサイズとその記録速度、プログラムが使用する LWP の数、およびプログラムの実行時間によって異なります。

データパケットには、イベント固有データとプログラム構造 (呼び出しスタック) に依存するデータが入っています。データのサイズはデータの種類に依存し、約 50 〜 100 バイトです。呼び出しスタックのデータは すべての呼び出しの復帰アドレスで構成され、アドレス 1 個あたりのサイズは 4 バイト、64 ビットの実行可能ファイルではアドレス 1 個あたり 8 バイトです。LWP ごとにデータパケットが実験に記録されます。Java プログラムの場合、対象となる呼び出しスタックは Java 呼び出しスタックとマシン呼び出しスタックの 2 つがあるため、ディスクに書き込まれるデータが増えます。

プロファイルデータパケットが記録される速度は、時間データの場合はプロファイル間隔、ハードウェアカウンタデータの場合はオーバーフロー値によって制御されます。ただし、これらのパラメータは、データの品質や、データ収集のオーバーヘッドによるプログラムパフォーマンスのひずみにも影響します。これらのパラメータ値が小さければ良い統計値が得られますが、オーバーヘッドは高くなります。プロファイル間隔とオーバーフロー値のデフォルト値は、良好な統計値を得ることとオーバーヘッドを抑えることの折衷点として慎重に選択されています。値が小さい場合、データ量が多いことを意味します。

プロファイル間隔が 10 ミリ秒で呼び出しスタックが小さく、パケットサイズが 100 バイトの時間ベースのプロファイル実験の場合、データは LWP 1 つあたり毎秒 10K バイトで記録されます。オーバーフロー値を 1000000、パケットサイズを 100 バイトとして、750MHz のプロセッサで実行された CPU サイクルと命令のデータを収集する、ハードウェアカウンタオーバーフローのプロファイル実験の場合は、LWP 1 つあたり毎秒 150K バイトの速度です。数百という深さを持つ呼び出しスタックを持つプログラムの場合は、この 10 倍以上の速度でデータが記録される可能性があります。

実験サイズの概算では、アーカイブファイルに使用されるディスク容量も考慮する必要がありますが、通常その量は、必要となるディスク容量全体のごく一部です (前節参照)。必要なディスク容量のサイズを確定できない場合は、実験を短時間だけ行なってみてください。この実験からアーカイブファイルのサイズを取得し (データ収集時間とは無関係)、プロファイルファイルのサイズを確認することによって、完全な実験のサイズを概算できます。

コレクタは、ディスク容量を割り当てるだけでなく、ディスクにプロファイルデータを書き込む前に、そのデータを格納するためのバッファーをメモリー内に確保します。現在、こうしたバッファーのサイズを指定する方法はありません。コレクタがメモリー不足になった場合、収集するデータ量を減らすようにしてください。

現在利用できる容量より実験の格納に必要となる容量の方が大きいと思われる場合には、実行の全体でなく一部だけのデータを収集することを検討してください。実行の一部についてのデータを収集するには、collect コマンドまたは dbx collector サブコマンドを使用するか、あるいはコレクタ API の呼び出しをプログラムに挿入します。collect コマンドや dbx collector サブコマンドを使用して、収集するプロファイルデータやトレースデータの総量を制限することもできます。


注 –

パフォーマンスアナライザが読み込めるパフォーマンスデータは、2G バイトまでです。


データの収集

パフォーマンスデータの収集は、スタンドアロンのパフォーマンスアナライザまたは IDE の「アナライザ」ウィンドウを使用して、次に示す方法で行うことができます。

次のデータ収集機能は、パフォーマンスツールの「収集」ダイアログボックスと collect コマンドでのみ利用できます。

collect コマンドによるデータの収集

collect コマンドを使用してコマンド行からコレクタを実行するには、次のコマンドを使用します。


% collect collect-options program program-arguments

ここで、collect-optionscollect コマンドのオプション、program はデータの収集対象のプログラム名、program-arguments はプログラムの引数です。

collect-options を指定しなかった場合は、デフォルトで時間ベースのプロファイルが有効になり、プロファイル間隔は約 10 ミリ秒になります。

コマンドオプションの一覧とプロファイルに使用可能なハードウェアカウンタ名の一覧を表示するには、引数を指定せずに collect コマンドを実行します。


% collect

ハードウェアカウンタの一覧については、「ハードウェアカウンタオーバーフローのプロファイルデータ」を参照してください。「ハードウェアカウンタオーバーフローのプロファイルに関する制限事項」も参照してください。

データ収集オプション

データ収集のオプションは、どのような種類のデータを収集するのかを制御します。データの種類については、「コレクタが収集するデータの内容」を参照してください。

データ収集オプションを指定しなかった場合、デフォルトは -p on で、デフォルトのプロファイル間隔 (約 10 ミリ秒) で時間ベースのプロファイルが行われます。このデフォルト設定は、-h オプションを使用することによってのみ無効にできます。

時間ベースのプロファイルを明示的に無効とし、すべてのトレースとハードウェアカウンタオーバーフロープロファイルを有効にしなかった場合、collect コマンドは警告メッセージを出力し、大域データだけを収集します。

-p option

時間ベースのプロファイルデータを収集します。option には次のいずれかの値を指定できます。

collect コマンドは、デフォルトで時間ベースのプロファイルデータを収集します。

-h counter_definition_1 ...[,counter_definition_n]

ハードウェアカウンタオーバーフローのプロファイルデータを収集します。カウンタ定義の数はプロセッサに依存します。 このオプションは、Linux オペレーティングシステムを実行しているシステムでも、perfctr パッチをインストールすると使用できるようになりました。このパッチは、http://user.it.uu.se/~mikpe/linux/perfctr/2.6/perfctr-2.6.15.tar.gz からダウンロードできます。

カウンタ定義には、プロセッサがハードウェアカウンタの属性をサポートしているかどうかに応じて、次のいずれかの形式を使用できます。

[+]counter_name[/ register_number][,interval ]

[+]counter_name[~ attribute_1=value_1]...[~attribute_n =value_n][/ register_number][,interval ]

プロセッサ固有の counter_name には、次のいずれかを指定できます。

複数のカウンタを指定する場合、それらのカウンタは異なるレジスタを使用する必要があります。同じレジスタが指定された場合、collect コマンドはエラーメッセージを出力して終了します。どちらのレジスタでもカウントできるカウンタもあります。

使用可能なカウンタの一覧を表示するには、引数を指定せずに collect コマンドを端末ウィンドウに入力します。「ハードウェアカウンタのリスト」に、カウンタの一覧があります。

ハードウェアカウンタがメモリーアクセスに関連するイベントをカウントする場合、カウンタ名の前に + 記号を付けて、カウンタのオーバーフローを発生させた命令の実際のプログラムカウンタアドレス (PC) の検索をオンにすることができます。バックトラッキングは SPARC プロセッサ上で、loadstoreload-store のいずれかのタイプのカウンタでのみ機能します。検索が成功すると、仮想 PC、物理 PC、および参照された有効アドレスがイベントデータパケットに格納されます。

一部のプロセッサでは、属性オプションをハードウェアカウンタへ関連付けることができます。 プロセッサが属性オプションをサポートしている場合は、collect コマンドを引数リストなしで実行すると、属性名を含むカウンタ定義が一覧表示されます。属性値は、10 進数または 16 進数形式で指定できます。

間隔 (オーバーフロー値) は、ハードウェアカウンタがオーバーフローしてオーバーフローイベントが記録されたときにカウントされたイベント数です。間隔は、次のいずれかに設定できます。

デフォルトでは、事前に各カウンタに定義されている通常のしきい値が使用されます。これらの値はカウンタの一覧に表示されます。「ハードウェアカウンタオーバーフローのプロファイルに関する制限事項」も参照してください。

-p オプションを明示的に指定せずに -h オプションを使用すると、時間ベースのプロファイルが無効となります。ハードウェアカウンタデータと時間ベースデータの両方を収集するには、 -h オプションと -p オプションの両方を指定する必要があります。

-s option

同期待ちトレースデータを収集します。option には次のいずれかの値を指定できます。

同期待ちのトレースデータは、Java モニターには記録されません。

-H option

ヒープトレースデータを収集します。option には次のいずれかの値を指定できます。

デフォルトでは、ヒープのトレースは無効です。ヒープトレースは Java プログラムについてはサポートされず、指定するとエラーとして処理されます。

-m option

MPI トレースデータを収集します。option には次のいずれかの値を指定できます。

デフォルトでは、MPI トレースは無効です。

呼び出しがトレースされる MPI 関数とトレースデータをもとに計算されるメトリックの詳細については、「MPI トレースデータ」を参照してください。

-S option

標本パケットを定期的に記録します。option には次のいずれかの値を指定できます。

デフォルトでは、1 秒間隔による定期的標本収集が有効になります。

-c option

カウントデータを記録します。SPARC プロセッサだけが対象です。


注 –

この機能を使用するには、Sun Studio 12 用 Add-on Cool Tools に含まれるバイナリインタフェースツール (BIT) が必要です。このツールは、http://cooltools.sunsource.net/ からダウンロードできます。BIT は、SPARC バイナリのパフォーマンスやテストスイートカバレージの測定用ツールです。


option には次のいずれかの値を指定できます。

-r option

スレッドアナライザ用に、データ競合検出またはデッドロック検出のデータを収集します。次のいずれかの値を指定できます。

collect -r コマンドとスレッドアナライザの詳細については、『Sun Studio 12: Thread Analyzer User’s Guide』および tha.1 のマニュアルページを参照してください。

実験制御オプション

-F option

派生プロセスのデータを記録するかどうかを制御します。option には次のいずれかの値を指定できます。

-F on オプションを指定すると、コレクタは、fork(2)、 fork1(2)、fork(3F)、vfork(2)、および exec(2) の関数とそのバリアントの呼び出しによって作成されたプロセスをたどります。vfork の呼び出しは、内部で fork1 の呼び出しに置換されます。

-F all オプションを指定すると、コレクタは、system(3C)、system(3F)、sh(3F)、および popen(3C)、および同様の関数の呼び出しによって作成されたものを含むすべての派生プロセス、そして関係する派生プロセスをたどります。

-F '= regexp ' オプションを指定すると、コレクタは、名前または系統が指定する正規表現と一致するすべての派生プロセスをたどります。正規表現については、regexp(5) のマニュアルページを参照してください。

派生プロセスのデータを収集するとき、コレクタは、派生プロセスごとに新しい実験を親の実験内に 1 つ開きます。これらの新しい実験は、次のように、下線、文字、および数字を実験接尾辞に追加することで命名されます。

たとえば初期プロセスの実験名が test.1.er の場合、3 回目の fork の呼び出しで作成された子プロセスの実験は test.1.er/_f3.er となります。この子プロセスが新しいイメージを実行した場合、対応する実験名は test.1.er/_f3_x1.er となります。この子プロセスが popen 呼び出しを使用して別のプロセスを作成した場合、実験名は test.1.er/_f3_x1_c1.er となります。

アナライザおよび er_print は、親の実験が読み取られたときに自動的に派生プロセスの実験を読み取りますが、派生プロセスの実験は、データ表示の対象として選択されません。

表示するデータをコマンド行から選択するには、er_printanalyzer にパス名を明示的に指定します。指定するパスには、親の実験名と、親ディレクトリ内の派生実験名を含める必要があります。

たとえば、test.1.er 実験の 3 回目の fork のデータを表示する場合は、次のように指定します。

er_print test.1.er/_f3.er

analyzer test.1.er/_f3.er

もう一つの方法として、関心のある派生の実験の明示的な名前を入れた実験グループファイルを用意する方法もあります。

アナライザで派生プロセスを調べるには、親の実験を読み込んで、「表示」メニューから「データをフィルタ」を選択します。実験のリストは、親の実験のみが選択されて表示されます。これを選択解除し、対象とする派生実験を選択します。


注 –

派生プロセスが追跡されている間に親プロセスが終了した場合、派生のデータ収集が継続する可能性があります。それに従って親の実験ディレクトリは拡大を続けます。


-j option

ターゲットプログラムが JVM の場合に Java プロファイルを有効にします。option には次のいずれかの値を指定できます。

-j オプションは、.class ファイルまたは .jar ファイルについてのデータを収集する場合は必要ありません。ただし、java 実行可能ファイルへのパスが JDK_HOME 環境変数または JAVA_PATH 環境変数に入っている必要があります。それから collect コマンド行でターゲットの program.class ファイルまたは .jar ファイルとして指定します。拡張子は付けても付けなくてもかまいません。

JDK_HOME または JAVA_PATH 環境変数で java のパスを定義できない場合や、Java HotSpot 仮想マシンによってコンパイルされたメソッドの認識を無効にしたい場合に、-j オプションを使用できます。このオプションを使用する場合、collect コマンド行で指定する program は 1.5_03 以降のバージョンの Java 仮想マシンであることが必要です。collect コマンドは program が JVM であるかどうかと ELF 実行可能ファイルであるかどうかを確認し、そうでない場合、collect はエラーメッセージを出力します。

64 ビット JVM を使用してデータを収集する場合、32 ビット JVM 用の java -d64 オプションを使用しないでください。これを使用すると、データは収集されません。collect コマンドの program 引数、またはこの項で説明している環境変数の 1 つに 64 ビット JVM のパスを指定してください。

-J java_argument

プロファイリングに使用する JVM に渡す引数を 1 つ指定します。-J オプションを指定し、Java プロファイリングを指定しなかった場合は、エラーが生成され、実験は実行されません。引数は、単一の引数として JVM に渡されます。複数の引数が必要な場合は、-J オプションを使用しないでください。この場合、collect コマンド行で、JVM のパスを明示的に指定し、-j on を使用して JVM のパスのあとに JVM の引数を追加します。

-l signal

signal というシグナルがプロセスへ送信されたときに標本パケットを記録します。

シグナルは、完全なシグナル名、先頭文字 SIG を省いたシグナル名、またはシグナル番号のいずれの形式でも指定できます。ただし、プログラムが使用するシグナル、または実行を終了するシグナルは指定しないでください。推奨するシグナルは SIGUSR1 および SIGUSR2 です。シグナルは、kill コマンドを使用してプロセスに送信できます。

-l および -y の両方のオプションを使用する場合は、それぞれのオプションに異なるシグナルを使用する必要があります。

プログラムに独自のシグナルハンドラがあるときにこのオプションを使用する場合には、-l で指定するシグナルが、阻止されたり、無視されたりすることなく、確実にコレクタのシグナルハンドラに渡されるようにする必要があります。

シグナルについては、signal(3HEAD) のマニュアルページを参照してください。

-t <所要時間>

データ収集の時間範囲を指定します。

<所要時間> は単数で指定でき、オプションで m または s 接尾辞を付けることができます。これらは、実験を終了する時間が分か秒かを示しています。デフォルトでは、所要時間は秒です。<所要時間> はハイフンで区切られた 2 つの数で指定することもできます。これは、1 つ目の時間が経過するまでデータ収集を停止し、そして、データ収集を始める時間を示しています。2 つ目の時間が経過すると、データ収集が終了されます。2 番目の数値がゼロの場合、最初の一時停止から、プログラムの実行が終了するまでデータが収集されます。実験が終了しても、ターゲットのプロセスは完了するまで実行を続けます。

-x

デバッガがそのプロセスに接続できるように、exec システムコールの終了時にターゲットプロセスを停止したままにします。dbx をプロセスに接続した場合には、dbx コマンドの ignore PROFignore EMT を使用して、収集シグナルが確実に collect コマンドに渡されるようにします。

-y signal[ ,r]

signal というシグナルで、データの記録を制御します。このシグナルがプロセスに送信されると、一時停止状態 (データは記録されない) と記録状態 (データは記録される) が切り替わります。ただし、このスイッチの状態に関係なく、標本ポイントは常に記録されます。

シグナルは、完全なシグナル名、先頭文字 SIG を省いたシグナル名、またはシグナル番号のいずれの形式でも指定できます。ただし、プログラムが使用するシグナル、または実行を終了するシグナルは指定しないでください。推奨するシグナルは SIGUSR1 および SIGUSR2 です。シグナルは、kill(1) コマンドを使用してプロセスに送信できます。

-l および -y の両方のオプションを使用する場合は、それぞれのオプションに異なるシグナルを使用する必要があります。

-y オプションに r 引数 (省略可能) を指定した場合、コレクタは記録状態で起動します。 それ以外の場合は、一時停止状態でコレクタが起動します。-y オプションを指定しなかった場合は、記録状態で起動します。

プログラムに独自のシグナルハンドラがあるときにこのオプションを使用する場合には、-y で指定するシグナルが、阻止されたり、無視されたりすることなく、確実にコレクタのシグナルハンドラに渡されるようにする必要があります。

シグナルについては、signal(3HEAD) のマニュアルページを参照してください。

出力オプション

-o experiment_name

記録する実験の名前として experiment_name を使用します。experiment_name 文字列は「.er」で終わる必要があり、そうでない場合、collect ユーティリティーはエラーメッセージを出力して終了します。

-d directory-name

directory-name というディレクトリに実験を格納します。このオプションは個別の実験にのみ適用され、実験グループには適用されません。ディレクトリが存在しない場合、collect ユーティリティーはエラーメッセージを出力して終了します。-g オプションでグループが指定されている場合は、グループファイルも directory-name へ書き込まれます。

-g group-name

実験を group-name という実験グループに含めます。group-name の末尾が .erg でない場合、collect ユーティリティーはエラーメッセージを出力して終了します。グループが存在する場合は、グループに実験が追加されます。group-name が絶対パスでない場合、-d でディレクトリを指定したとすれば、実験グループはディレクトリ directory-name に設定され、それ以外は現在のディレクトリに設定されます。

-A option

ターゲットプロセスで使用されるロードオブジェクトを、記録済み実験に保管またはコピーするかどうかを管理します。オプションには、次のいずれかの値を指定できます。

実験データが記録されたマシンとは異なるマシンに実験データをコピーするか、異なるマシンから実験データを読み取る場合は、 - A copy を指定します。このオプションを使用しても、ソースファイルまたはオブジェクトファイルは実験にコピーされません。実験データのコピー先のマシン上で、これらのファイルにアクセスできるかどうかを確認してください。

-L size

記録するプロファイルデータの量を size メガバイトに制限します。この制限は、時間ベースのプロファイルデータ、ハードウェアカウンタオーバーフローのプロファイルデータ、および同期待ちのトレースデータの合計に適用されますが、標本ポイントには適用されません。この制限値は概数にすぎないので、この値を超えることは可能です。

制限に達すると、それ以上のプロファイルデータは記録されませんが、ターゲットプロセスが終了するまで実験はオープン状態となります。定期的な標本収集が有効である場合、標本ポイントの書き込みが継続されます。

記録されるデータのデフォルトの制限値は 2000M バイトです。この制限値が選択されたのは、2G バイトを超えるデータの実験をパフォーマンスアナライザが処理することができないためです。制限を外すには、sizeunlimited または none に設定します。

-O file

collect 自体の全出力を指定された file に付加しますが、生成されたターゲットからの出力はリダイレクトしません。ファイルが /dev/null に設定されている場合は、エラーメッセージを含む collect の全出力が抑制されます。

その他のオプション

-C comment

実験の notes ファイルにコメントを追加します。最大 10 個の -C オプションを指定できます。notes ファイルの内容は、実験のヘッダーの先頭に付加されます。

-n

ターゲットを実行しませんが、ターゲットが実行されれば生成されたはずの実験の詳細を出力します。このオプションは「ドライラン」オプションです。

-R

パフォーマンスアナライザの Readme のテキストバージョンを端末ウィンドウに表示します。readme が見つからない場合は、警告が出力されます。これ以降に指定した引数は検査されず、これ以外の処理は行われません。

-V

collect コマンドの現在のバージョンを表示します。これ以降に指定した引数は検査されず、これ以外の処理は行われません。

-v

collect コマンドの現在のバージョンと、実行中の実験に関する詳細情報を表示します。

collect ユーティリティーによる動作中のプロセスからのデータの収集

Solaris OS では、collect ユーティリティーで -P pid オプションを使用して、指定する PID のプロセスに接続し、そのプロセスのデータを収集できます。collect コマンドのその他のオプションは dbx 用のスクリプトに変換され、そのスクリプトを実行してデータが収集されます。時間ベースのプロファイルデータ (-p オプション) とハードウェアカウンタオーバーフローのプロファイルデータ (-h オプション) だけを収集できます。トレースデータはサポートされていません。

-p オプションを明示的に指定せずに -h オプションを使用すると、時間ベースのプロファイルが無効となります。ハードウェアカウンタデータと時間ベースデータの両方を収集するには、 -h オプションと -p オプションの両方を指定する必要があります。

Procedurecollect ユーティリティーを使用して動作中のプロセスからデータを収集する

  1. プログラムのプロセス ID (PID) を調べます。

    コマンド行からプログラムを起動してバックグラウンドで実行している場合は、シェルによってその PID が標準出力に出力されます。その他の場合は、次のコマンドを使用し、プログラムの PID を調べることができます。


    % ps -ef | grep program-name
    
  2. collect コマンドを使用してプロセスのデータの収集を有効にし、オプションのパラメータを適宜設定します。


    % collect -P pid collect-options
    

    コレクタのオプションについては、「データ収集オプション」を参照してください。時間ベースのプロファイルについては、-p optionを参照してください。ハードウェアカウンタオーバーフローのプロファイルについては、-h optionを参照してください。

dbx collector サブコマンドによるデータの収集

この節では、dbx からコレクタを実行する方法、また dbx 内の collector コマンドで使用できる各サブコマンドについて説明します。

Proceduredbx からコレクタを実行する

  1. 次のコマンドを使用し、dbx にプログラムを読み込みます。


    % dbx program
    
  2. collector コマンドを使用してデータの収集を有効にし、データの種類を選択し、オプションのパラメータを適宜設定します。


    (dbx) collector subcommand
    

    利用可能な collector サブコマンドの一覧を表示するには、次のコマンドを使用します。


    (dbx) help collector
    

    サブコマンドごとに collector コマンドを 1 つ使用する必要があります。

  3. 使用する dbx のオプションを設定し、プログラムを実行します。

    指定したサブコマンドに誤りがある場合は、警告メッセージが出力され、サブコマンドは無視されます。このあとに、collector の全サブコマンドをまとめます。

データ収集のサブコマンド

ここでは、コレクタが収集するデータの種類を制御するサブコマンドをまとめています。実験がアクティブな場合は、警告メッセージが出力され、サブコマンドは無視されます。

profile option

時間ベースのプロファイルデータの収集を制御します。option には次のいずれかの値を指定できます。

hwprofile option

ハードウェアカウンタオーバーフローのプロファイルデータの収集を制御します。ハードウェアカウンタオーバーフローのプロファイル機能をサポートしていないシステム上でこの機能を有効にしようとすると、dbx から警告メッセージが返され、コマンドは無視されます。option には次のいずれかの値を指定できます。

synctrace option

同期待ちトレースデータの収集を制御します。option には次のいずれかの値を指定できます。

heaptrace option

ヒープトレースデータの収集を制御します。option には次のいずれかの値を指定できます。

デフォルトでは、コレクタはヒープのトレースデータを収集しません。

mpitrace option

MPI トレースデータの収集を制御します。option には次のいずれかの値を指定できます。

デフォルトでは、コレクタは MPI のトレースデータを収集しません。

tha option

スレッドアナライザ用に、データ競合検出またはデッドロック検出のデータを収集します。次のいずれかの値を指定できます。

スレッドアナライザについては、『Sun Studio 12: Thread Analyzer User’s Guide』および tha.1 のマニュアルページを参照してください。

sample option

標本収集モードを制御します。option には次のいずれかの値を指定できます。

デフォルトでは、標本収集間隔 value が 1 秒での定期的な標本収集が有効となります。

dbxsample { on | off }

dbx がターゲットプロセスを停止したときに、標本を記録するかどうかを制御します。キーワードの意味は、次のとおりです。

デフォルトでは、dbx がターゲットプロセスを停止したとき、標本が記録されます。

実験制御のサブコマンド

disable

データの収集を無効にします。プロセスが動作中でデータを収集中の場合は、その実験が終了し、データ収集が無効になります。プロセスが動作中でデータ収集が無効になっている場合、警告が出され、このサブコマンドは無視されます。プロセスが動作していない場合は、以降の実行のデータ収集が無効になります。

enable

データの収集を有効にします。プロセスが動作していてデータ収集が無効であった場合、データ収集が有効になって新しい実験が開始されます。プロセスが動作中でデータ収集が有効になっている場合、警告が出され、このサブコマンドは無視されます。プロセスが動作していない場合は、以降の実行のデータ収集が有効になります。

プロセスの動作中、データ収集は何回でも有効にしたり、無効にしたりできます。データ収集を有効にするたびに、新しい実験が作成されます。

pause

実験を開いたまま、データの収集を一時停止します。コレクタが一時停止している間、標本ポイントは記録されません。標本は一時停止の前に生成され、再開直後に別の標本が生成されます。データの収集がすでに一時停止されている場合、このサブコマンドは無視されます。

resume

pause が実行されたあとに、データの収集を再開します。データ収集中は、このサブコマンドは無視されます。

sample record name

name のラベルが付いた標本パケットを記録します。ラベルは、パフォーマンスアナライザの「イベント」タブで表示されます。

出力のサブコマンド

次のサブコマンドは、実験の格納オプションを指定します。実験がアクティブな場合は、警告メッセージが出力され、サブコマンドは無視されます。

archive mode

実験を保管するためのモードを設定します。 mode には次のいずれかの値を指定できます。

異なるマシンに実験を移動するか、別のマシンから実験を読み取る場合は、ロードオブジェクトのコピーを有効にする必要があります。実験がアクティブな場合、警告が出され、このコマンドは無視されます。このコマンドを使用しても、ソースファイルまたはオブジェクトファイルは実験にコピーされません。

limit value

記録するプロファイルデータの量を value メガバイトに制限します。この制限は、時間ベースのプロファイルデータ、ハードウェアカウンタオーバーフローのプロファイルデータ、および同期待ちのトレースデータの合計に適用されますが、標本ポイントには適用されません。この制限値は概数にすぎないので、この値を超えることは可能です。

制限に達すると、それ以上のプロファイルデータは記録されませんが、実験はオープンのままで標本ポイントの記録は継続します。

記録されるデータのデフォルトの制限値は 2000M バイトです。この制限値が選択されたのは、2G バイトを超えるデータの実験をパフォーマンスアナライザが処理することができないためです。制限を外すには、valueunlimited または none に設定します。

store option

実験の格納先を指定します。 実験がアクティブな場合、警告が出され、このコマンドは無視されます。option には次のいずれかの値を指定できます。

情報のサブコマンド

show

すべてのコレクタ制御の、現在の設定を表示します。

status

開かれている実験の状態を報告します。

dbx による動作中のプロセスからのデータの収集

コレクタでは、動作中のプロセスからデータを収集できます。プロセスがすでに dbx の制御下にある場合は、プロセスを一時停止し、これまでに説明した方法を使用してデータ収集を有効にすることができます。

プロセスが dbx の制御下にない場合は、collect –P pid コマンドを使用して、実行中のプロセスからデータを収集できます。詳細は、collect ユーティリティーによる動作中のプロセスからのデータの収集」を参照してください。プロセスに dbx を接続し、パフォーマンスデータを収集し、プロセスから切り離して、プロセスの実行を継続することもできます。選択した派生プロセスのパフォーマンスデータを収集するには、各プロセスに dbx を接続する必要があります。

Proceduredbx の制御下にない動作中のプロセスからデータを収集する

  1. プログラムのプロセス ID (PID) を調べます。

    コマンド行からプログラムを起動していて、バックグラウンドで実行している場合は、シェルによってその PID が標準出力に出力されます。その他の場合は、次のように入力してプログラムの PID を調べることができます。


    % ps -ef | grep program-name
    
  2. プロセスに接続します。

    dbx から、次のように入力します。


    (dbx) attach program-name pid
    

    dbx をまだ実行していない場合は、次のように入力します。


    % dbx program-name pid
    

    実行中のプロセスに接続すると、そのプロセスが一時停止します。

    プロセスへの接続については、『Sun Studio 12: Debugging a Program With dbx』を参照してください。

  3. データの収集を開始します。

    dbx から、collector コマンドを使用してデータ収集パラメータを設定し、cont コマンドを使用してプロセスを再開します。

  4. プロセスから切り離します。

    データの収集を完了したら、プログラムを一時停止し、dbx からプロセスを切り離します。

    dbx から、次のように入力します。


    (dbx) detach
    

動作中のプロセスからのトレースデータの収集

トレースデータを収集する場合は、プログラムを実行する前に、コレクタライブラリの libcollector.so を事前に読み込んでおく必要があります。 これは、このライブラリによって、データの収集を可能にする実関数にラッパーが提供されるためです。また、コレクタは、ほかのシステムライブラリの呼び出しにもラッパー関数を追加し、それによって完全なパフォーマンスデータを確保できます。コレクタライブラリを事前に読み込まなかった場合、ラッパー関数は挿入できません。コレクタがシステムライブラリ関数に割り込む方法の詳細については、「システムライブラリの使用」を参照してください。

libcollector.so を事前に読み込むには、次の表に示すように、環境変数を使用してライブラリ名とライブラリパスの両方を設定する必要があります。ライブラリ名を設定するには、環境変数 LD_PRELOAD を使用します。ライブラリのパスを設定するには、環境変数 LD_LIBRARY_PATHLD_LIBRARY_PATH_32、または LD_LIBRARY_PATH_64 を使用します。LD_LIBRARY_PATH は、_32_64 バリアントが定義されていない場合に使用します。これらの環境変数をすでに定義している場合は、新しい値を追加してください。

表 3–2 libcollector.so ライブラリを事前に読み込むための環境変数の設定

環境変数 

値 

LD_PRELOAD

libcollector.so

LD_LIBRARY_PATH

/opt/SUNWspro/prod/lib/dbxruntime

LD_LIBRARY_PATH_32

/opt/SUNWspro/prod/lib/dbxruntime

LD_LIBRARY_PATH_64

/opt/SUNWspro/prod/lib/v9/dbxruntime

LD_LIBRARY_PATH_64

/opt/SUNWspro/prod/lib/amd64/dbxruntime

Sun Studio ソフトウェアが /opt/SUNWspro 以外にインストールされている場合は、システム管理者に正しいパスを確認してください。LD_PRELOAD にフルパスを設定することもできますが、そのようにすると、SPARC V9 の 64 ビットアーキテクチャーを使用するときに問題が発生する可能性があります。


注 –

実行が終了したら、LD_PRELOADLD_LIBRARY_PATH の設定を削除し、同じシェルから起動されるほかのプログラムが設定の影響を受けないようにしてください。


すでに実行中の MPI プログラムからデータを収集する場合は、プロセスごとに 1 つの dbx インスタンスを接続し、それらのプロセスごとにコレクタを有効にする必要があります。MPI ジョブのプロセスに dbx を接続すると、各プロセスが停止され、別々の時間に再起動されます。この時間差によって MPI プロセス間のインタラクションに変化が生じ、収集するパフォーマンスデータに影響を及ぼす可能性があります。この問題の影響を最小限にするための 1 つの方法に、 pstop(1) コマンドを使用してすべてのプロセスを停止することがあります。ただし、プロセスを一度 dbx に接続すると、dbx からそれらのプロセスを再開する必要があり、そのときに時間的な遅延が発生して、MPI プロセスの同期に影響が出ることがあります。「MPI プログラムからのデータの収集」も参照してください。

MPI プログラムからのデータの収集

コレクタは、MPI (Message Passing Interface) ライブラリを使用するマルチプロセスプログラムからパフォーマンスデータを収集できます。Sun HPC ClusterToolsTM 7 ソフトウェアには Open MPI ライブラリが付属し、ClusterTools 5 と ClusterTools 6 ソフトウェアには Sun MPI ライブラリが付属します。ClusterTools ソフトウェアは http://www.sun.com/software/products/clustertools/ から入手できます。

ClusterTools 7 使用時に並列ジョブを開始するには、Open Run-Time Environment (ORTE) コマンドの mpirun を使用します。

ClusterTools 5 または ClusterTools 6 の使用時に並列ジョブを開始するには、Sun Cluster Runtime Environment (CRE) コマンドの mprun を使用します。

詳細は、Sun HPC ClusterTools のマニュアルを参照してください。

MPI と MPI 規格については、MPI の Web サイト http://www.mcs.anl.gov/mpi/ を参照してください。Open MPI については、Web サイト http://www.open-mpi.org/ を参照してください。

MPI とコレクタの実装方法により、MPI プロセスごとに個別の実験が作成されます。これらの実験は、それぞれ一意の名前を持つ必要があります。実験の格納場所と格納方法は、MPI ジョブから利用可能なファイルシステムの種類に依存します。実験の格納については、次の節、「MPI 実験の格納」を参照してください。

MPI ジョブからデータを収集するには、MPI の下で collect コマンドを実行する方法か、MPI の下で dbx を起動して dbx collector サブコマンドを使用する方法があります。これらの操作については、「MPI 下での collect コマンドの実行」「MPI の下で dbx を起動することによるデータ収集」を参照してください。

MPI 実験の格納

マルチプロセス環境は複雑になることがあるので、MPI プログラムからパフォーマンスデータを収集するときは、MPI 実験の格納に関するいくつかの問題に留意する必要があります。これらは、データの収集と格納の効率性、実験の命名に関係している問題です。MPI 実験をはじめとする実験の命名については、 「収集データの格納場所」を参照してください。

パフォーマンスデータを収集する MPI プロセスは、それぞれ独自の実験を作成します。実験を作成するとき、MPI プロセスは実験ディレクトリをロックします。このため、ほかの MPI プロセスがそのディレクトリを使用するには、ロックが解除されるのを待つ必要があります。つまり、あらゆる MPI プロセスからアクセス可能なファイルシステムに実験を格納した場合、実験は順次に作成されますが、各 MPI プロセスにローカルのファイルシステムに格納した場合は、すべての実験が同時に作成されます。

コレクタで実験名が作成されるようにすれば、実験名や格納場所に関する問題を回避できます。次の節、「デフォルトの MPI 実験名」を参照してください。

デフォルトの MPI 実験名

実験名を指定しなかった場合、デフォルトの実験名が使用されます。コレクタは MPI ランクに基づき、標準形式の experiment.m.er で実験名を作成します。 この場合の m は MPI ランクです。experiment は、実験グループが指定された場合は実験グループ名で、それ以外の場合は test になります。共通ファイルシステムまたはローカルファイルシステムのどちらを使用しているかに関係なく、実験名は一意です。つまり、ローカルファイルシステムを使用して実験を記録し、それらのファイルを共通のファイルシステムにコピーして実験グループファイルを再構築する場合、実験名を変更する必要はありません。ほとんどの場合、すべてのファイルシステムで名前が一意になるように、コレクタで実験名が作成されるようにしてください。

デフォルト以外の MPI 実験名の指定

実験を共通のファイルシステムに格納し、標準形式 experiment. n.er で実験名を指定した場合、実験のたびに n の値が増分されるときに実験名が一意になります。実験は、MPI プロセスによって実験ディレクトリのロックが取得された順序で番号が付けられるので、プロセスの MPI ランクに対応する保証はありません。動作中の MPI ジョブ内の MPI プロセスに dbx を接続した場合、実験の番号は、接続した順序によって決まります。

各実験をそれぞれローカルのファイルシステムに格納し、明示的な実験名を指定すると、実験の名前が同じになる可能性があります。たとえば node0node1node2node3 の 4 つのシングルプロセッサノードを持つクラスタにわたって、MPI ジョブを実行したとします。 各ノードには /scratch という名前のローカルディスクがあり、このディスク上のディレクトリ username に実験を格納します。MPI ジョブによって作成される実験は、次のフルパス名を持ちます。


node0:/scratch/username/test.1.er
node1:/scratch/username/test.1.er
node2:/scratch/username/test.1.er
node3:/scratch/username/test.1.er

ノード名を含むフルネームは一意ですが、それぞれの実験ディレクトリ内に test.1.er という名前の実験が存在します。MPI ジョブの完了後に実験を共通の場所に移動する場合は、名前が一意であることを確認してください。たとえば、自分のホームディレクトリ (すべてのノードからアクセス可能と仮定) に実験を移動して、実験名を変更するには、次のコマンドを使用します。


rsh node0 ’er_mv /scratch/username/test.1.er test.0.er’
rsh node1 ’er_mv /scratch/username/test.1.er test.1.er’
rsh node2 ’er_mv /scratch/username/test.1.er test.2.er’
rsh node3 ’er_mv /scratch/username/test.1.er test.3.er’

大規模な MPI ジョブの場合は、スクリプトを使用して共通の場所に実験を移動することもできます。UNIX® コマンド cp または mv は使用せず、上の例、または 「実験の操作」 に示す er_cp または er_mv を使用してください。

利用可能なローカルファイルシステムが不明な場合は、df -lk コマンドを使用するか、システム管理者に確認してください。実験を格納するディレクトリは、一意に定義されていて、ほかの実験に使用されていない既存のディレクトリであることを常に確認してください。また、ファイルシステムに、実験用の十分な空き容量があることを確認してください。必要なディスク容量の概算方法については、「必要なディスク容量の概算」を参照してください。


注 –

コンピュータ間やノード間で実験をコピーまたは移動すると、注釈付きのソースコードや注釈付きの逆アセンブリコード内のソース行を表示できなくなる場合があります。 これらのコードを表示するには、実験に使用されたロードオブジェクトとソースファイル、または同じパスとタイムスタンプを持つコピー へのアクセス権が必要があります。


MPI 下での collect コマンドの実行

MPI の制御下で collect コマンドを使用してデータを収集するには、ClusterTools のバージョンに応じて、次の構文を使用します。

Sun HPC ClusterTools 7:


% mpirun -np n 
collect [collect-arguments] program-name
 [program-arguments]

Sun HPC ClusterTools 6 以前:


% mprun -np n 
collect [collect-arguments] program-name
 [program-arguments]

ここで、n は MPI で作成されるプロセス数です。この手順では、collectn 個の個別のインスタンスが作成され、それぞれのインスタンスで実験が記録されます。実験を格納する場所と方法については、「収集データの格納場所」の節をお読みください。

さまざまな MPI ランから集めた実験結果が別々に格納されるようにするために、MPI ランごとに -g オプションで実験グループを作成することができます。実験グループはすべての MPI プロセスからアクセスできるファイルシステムに保存してください。実験グループを作成すると、1 つの MPI ランに関する複数の実験をパフォーマンスアナライザに容易に読み込むこともできます。グループを作成する代わりに、-d オプションで各 MPI ランに個別のディレクトリを指定することもできます。

MPI の下で dbx を起動することによるデータ収集

MPI の制御下で dbx を起動し、データを収集するには、次の構文を使用します。

Sun HPC ClusterTools 7:


% mpirun -np n dbx program-name < collection-script

Sun HPC ClusterTools 6 以前:


% mprun -np n dbx program-name < collection-script

どちらの場合も、n は MPI で作成されるプロセス数であり、collection-script はデータ収集をセットアップして起動するのに必要なコマンドを含む dbx スクリプトです。この手順では、dbxn 個の個別のインスタンスが作成され、それぞれのインスタンスで 1 つの MPI プロセスの実験が記録されます。実験名を定義しなかった場合、実験には MPI ランクのラベルが付けられます。実験を格納する場所と方法については、「MPI 実験の格納」の節をお読みください。

収集スクリプトを使用し、プログラム内で MPI_Comm_rank() を呼び出すことで、実験に MPI ランクの名前を付けることができます。たとえば、C プログラムには次の行を挿入します。


ier = MPI_Comm_rank(MPI_COMM_WORLD,&me);

Fortran プログラムには次の行を挿入します。


call MPI_Comm_rank(MPI_COMM_WORLD, me, ier)

この呼び出しを行 17 に挿入した場合は、次のようなスクリプトを使用することができます。


stop at 18
run program-arguments
rank=$[me]
collector enable
collector store filename experiment.$rank.er
cont
quit
 

ppgsz での collect の使用

ppgsz(1) で collect を使用することができます。このためには、ppgsz コマンド上で -F on フラグまたは -F all フラグを指定して collect を実行します。親の実験は ppgsz 実行可能ファイル上にあり、無関係です。パスに 32 ビット版の ppgsz があり、64 ビットプロセス対応のシステムで実験を実行すると、ppgsz によって最初にその 64 ビット版が exec されて、_x1.er が作成されます。この実行可能ファイルはフォークし、_x1_f1.er が作成されます。

子プロセスは、exec が成功するまで、パス上の最初のディレクトリ、次に 2 つ目のディレクトリというように、指定された名前のターゲットの exec を試みます。たとえば 3 回目の試みが成功した場合、最初の 2 つの派生の実験にはそれぞれ _x1_f1_x1.er_x1_f1_x2.er という名前が付けられ、両者は完全に空です。ターゲット上の実験は成功した exec (この例では 3 番目) から得られたものであり、_x1_f1_x3.er という名前で、親の実験の下に格納されます。この実験は、test.1.er/_x1_f1_x3.er に対してアナライザまたは er_print ユーティリティーを呼び出すことによって直接処理できます。

上記の例と同じパスで、初期プロセスが 64 ビットの ppgsz であるか、32 ビットカーネル上で 32 ビットの ppgsz を呼び出した場合、本当のターゲットを exec するフォークの子のデータは _f1.er に格納され、本当のターゲットの実験は _f1_x3.er に格納されます。