パフォーマンス解析の第一段階は、データ収集です。この章では、データ収集のための準備、収集データの格納場所、データの収集方法、およびデータ収集の管理方法について説明します。データそのものの詳細については、第 2 章「パフォーマンスデータ」を参照してください。
この章では、次の内容について説明します。
プログラムのコンパイル時には、ほとんどのオプションを使用してデータの収集および解析を行うことができますが、収集対象とパフォーマンスアナライザでの表示対象に影響するオプションがいくつかあります。プログラムのコンパイルとリンクを行う際に考慮すべき事柄について、このあとの各項で説明します。
注釈付き「ソース」と「逆アセンブリ」解析にソースコードを表示し、「行」解析にソース行を表示するには、-g コンパイラオプション (C++ でフロントエンドインライン化を有効にするには -g0) で対象のソースファイルをコンパイルして、デバッグシンボル情報を作成します。デバッグシンボル情報の形式は、-xdebugformat=(dwarf|stabs) で指定し、スタブと DWARF2 のいずれかとすることができます。デフォルトのデバッグ形式は dwarf です。
データ空間プロファイルを許可するコンパイルオブジェクトのデバッグ情報を準備するには、-xhwcprof -xdebugformat=dwarf と任意の最適化レベルを指定してコンパイルします。データ空間プロファイルは現時点では SPARC® プロセッサだけが対象です。現在は、最適化を行わないと、この機能は使用できません。「データオブジェクト」解析でプログラムデータオブジェクトを表示するには、-g (または C++ の場合は -g0) も追加して十分なシンボル情報を取得します。
DWARF 形式のデバッグ用シンボルで構築された実行可能ファイルやライブラリには、各成分オブジェクトファイルのデバッグシンボルのコピーが自動的に取り込まれます。スタブ形式のデバッグ用シンボルで構築された実行可能ファイルとライブラリにも、各成分オブジェクトファイルのデバッグシンボルのコピーが取り込まれます。ただし、それらの実行可能ファイルとライブラリが、各種オブジェクトファイル内と実行可能ファイル内にスタブシンボルを残す -xs オプションを使用してリンクされている必要があります。この情報の取り込みは、オブジェクトファイルを移動したり、削除したりする必要がある場合に特に有用です。すべてのデバッグ用シンボルが実行可能ファイルとライブラリ自体にあるので、実験とプログラム関連ファイルを別の場所に容易に移動できます。
プログラムをコンパイルするときに、-dn および -Bstatic コンパイラオプションを使用して動的リンクを無効にしないでください。 完全に静的にリンクされたプログラムのデータを収集しようとしても、コレクタからエラーメッセージが返され、データは収集されません。このエラーが発生する原因は、コレクタを実行したときに、コレクタライブラリが動的に読み込まれるためです。
システムライブラリを静的リンクしないでください。システムライブラリを静的リンクしてしまうと、トレースデータを何も収集できなくなることがあります。また、コレクタライブラリ libcollector.so へもリンクしないでください。
何らかのレベルの最適化を有効にしてプログラムをコンパイルすると、コンパイラが実行順序を変更できるため、プログラム内の行の順序どおりにコードが実行されなくなります。この場合、パフォーマンスアナライザは、最適化されたコードについて収集された実験データを解析できますが、しばしば、逆アセンブリレベルでパフォーマンスアナライザが提供するデータを元のソースコード行に対応付けることが困難になります。また、コンパイラが末尾呼び出しの最適化を行う場合には、呼び出しシーケンスが予想とは異なっているように見えることがあります。詳細は、「末尾呼び出しの最適化」を参照してください。
javac による Java プログラムのコンパイルに特別なアクションは不要です。
データ収集と解析の準備のためにプログラムに対して行う特別な作業はありません。次の処理のうち、いずれか 1 つでも行うプログラムの場合には、後述の該当する節を読んでください。
シグナルハンドラをインストールする
システムライブラリを明示的かつ動的に読み込む
関数を動的にコンパイルする
プロファイルする派生プロセスを作成する
非同期 I/O ライブラリを使用する
プロファイルタイマーまたはハードウェアカウンタ API を直接使用する
setuid(2) を呼び出すか、setuid ファイルを実行する
また、データ収集をプログラムから制御する場合も、該当する節を読んでください。
多くのプログラムは、次のような機能を使用して、動的に割り当てられたメモリーに依存しています。
malloc、valloc、alloca (C/C++)
new (C++)
スタック局所変数 (Fortran)
MALLOC、MALLOC64 (Fortran)
初期値の設定としてメモリーの割り当て方法が明示的に規定されていないかぎり、プログラムが動的に割り当てられるメモリーの初期内容に依存しないように注意する必要があります。たとえば、malloc(3C) のマニュアルページにある calloc と malloc の説明を比較してください。
動的に割り当てられるメモリーを使用するプログラムを単独で実行すると、正常に機能しているように見えることがありますが、パフォーマンスデータの収集を有効にした状態で実行すると、問題が起きることがあります。そのときの症状には、予期しない浮動小数点演算動作、セグメント例外、またはアプリケーション固有のエラーメッセージなどが含まれる場合があります。
こうした症状は、アプリケーションが単独で実行されたときには、初期化されていないメモリーの値が動作に影響ないものであっても、パフォーマンスデータの収集ツールとの組み合わせで実行されたときに別の値が設定されることによって、発生する場合があります。この場合は、パフォーマンスツールの問題ではありません。動的に割り当てられたメモリーの内容に依存するアプリケーションのどれにも、潜在的な問題があります。別途、明示的に規定されていないかぎり、オペレーティングシステムは、どのような内容であれ、動的に割り当てられたメモリー上の内容の提供を自由に行えます。現在のオペレーティングシステムが動的に割り当てられるメモリーに必ず特定の値を設定するようになっていたとしても、将来オペレーティングシステムのリリースが変わったとき、あるいはプログラムを別のオペレーティングシステムに移植した場合には、こうした潜在的な問題によって、予期しない動作が発生する可能性があります。
次のツールが、こうした潜在的な問題の発見に役立ちます。
f95 -xcheck=init_local
詳細は、『Fortran ユーザーズガイド』または f95(1) のマニュアルページを参照してください。
lint ユーティリティー
詳細は、『C ユーザーズガイド』または lint(1) のマニュアルページを参照してください。
dbx 下での実行時チェック
詳細は、『dbx コマンドによるデバッグ 』または dbx(1) のマニュアルページを参照してください。
Rational Purify
コレクタは、さまざまなシステムライブラリの関数に割り込み、トレースデータを収集し、データ収集の完全性を確保します。コレクタがライブラリ関数の呼び出しに割り込む状況を次に示します。
同期待ちトレースデータの収集。コレクタは、Solaris 9 OS で Solaris スレッドライブラリ libthread.so の関数に対して、また Solaris 10 OS で Solaris C ライブラリ libc.so の関数に対して割り込み処理を行います。
ヒープトレースデータの収集。コレクタは、malloc、realloc、memalign、free の関数に割り込みます。これらの関数は、C 標準ライブラリ libc.so のほか、libmalloc.so や libmtmalloc.so などのライブラリにあります。
MPI トレースデータの収集。コレクタは、Solaris MPI ライブラリ libmpi.so の関数に割り込みます。
時間データの完全性の確保。コレクタは setitimer に割り込み、プログラムがプロファイルタイマーを使用しないようにします。
ハードウェアカウンタデータの完全性の確保。コレクタはハードウェアカウンタライブラリ libcpc.so の関数に割り込み、プログラムがカウンタを使用しないようにします。プログラムからこのライブラリの関数への呼び出しは、値 -1 を返します。
派生プロセスに対するデータ収集の有効化。コレクタは、fork(2)、fork1(2)、vfork(2)、fork(3F)、system(3C)、system(3F)、sh(3F)、popen(3C)、exec(2) の関数とそのバリアントに割り込みます。 vfork の呼び出しは、内部で fork1 の呼び出しに置き換えられます。これらの割り込み処理が行われるのは、collect コマンドの場合だけです。
コレクタによる SIGPROF シグナルおよび SIGEMT シグナルの処理の保証。コレクタは sigaction に割り込み、シグナルハンドラがこれらのシグナル用のプライマリシグナルハンドラであるかどうかを確認します。
次のような環境では、割り込みが成功しません。
割り込み対象関数が入っているライブラリとプログラムを静的にリンクした場合。
コレクタライブラリが事前読み込みされていない実行中アプリケーションに dbx を接続した場合。
これらのライブラリのいずれか 1 つを動的に読み込み、このライブラリの中でだけ検索することによってシンボルを解決する場合。
コレクタが割り込み処理を行えなかった場合には、パフォーマンスデータが消去されたり無効になったりする可能性があります。
コレクタは、シグナルを 2 つ使用してプロファイルデータを収集します。全実験用の SIGPROF と、ハードウェアカウンタ実験専用の SIGEMT です。コレクタはこれらのシグナルのそれぞれを対象としてシグナルハンドラをインストールします。シグナルハンドラは自身のシグナルをインターセプトして処理しますが、ほかのシグナルは、インストールされているほかのシグナルハンドラに引き渡します。プログラムがこれらのシグナル用に独自のシグナルハンドラをインストールすると、コレクタは自分のシグナルハンドラをプライマリハンドラとして再インストールし、それによって完全なパフォーマンスデータが確保されます。
collect コマンドでは、ユーザー指定のシグナルを使用してデータ収集の一時停止と再開、および標本の記録を行えます。それらのシグナルはコレクタによって保護されませんが、ユーザーハンドラがインストールされている場合は、実験に警告が書き出されます。コレクタとアプリケーションによる指定シグナルの使用が互いに競合しないように、ユーザーが責任を持って確認する必要があります。
コレクタによってインストールされたシグナルハンドラは、システムコールがシグナル配信のために中断されないようにするためのフラグを設定します。この方法では、プログラムのシグナルハンドラがシステムコールの中断を許可するようにフラグを設定した場合に、プログラムの動作が変わる可能性があります。動作が変化する重要な例としては、非同期キャンセル処理に SIGPROF を使用し、システムコールの中断を行う非同期入出力ライブラリ libaio.so があります。コレクタライブラリ libcollector.so がインストールされている場合は必ず、キャンセルシグナルの到着が非同期入出力操作の取り消しに間に合わないほど遅れます。
コレクタライブラリを事前読み込みしないままプロセスに dbx を接続してパフォーマンスデータ収集を有効にし、そのあとでプログラムが自分のシグナルハンドラをインストールすると、コレクタは自分のシグナルハンドラを再インストールしません。この場合、プログラムのシグナルハンドラは、 パフォーマンスデータが失われないように、SIGPROF と SIGEMT のシグナルが確実に渡されるようにする必要があります。プログラムのシグナルハンドラがシステムコールを中断した場合のプログラムの動作とプロファイルの動作は、コレクタライブラリが事前読み込みされた場合の動作と異なります。
動的ローダーによって課される制約は、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++ インタフェースにアクセスする方法は 2 通りあります。
collectorAPI.h を取り込み、基になっている libcollector.so API 関数の有無をチェックする実関数が含まれている -lcollectorAPI とリンクする。
この方法では、API ライブラリとリンクする必要があります。この方法は、あらゆる環境下で有効です。有効な実験がない場合、API 呼び出しは無視されます。
基になっている libcollector.so API 関数の有無をチェックするマクロを含む、libcollector.h を取り込む。
この方法は、メインの実行可能ファイル内で使用する場合と、プログラムの起動と同時にデータ収集を開始する場合にのみ有効です。dbx を使用してプロセスに接続する場合や、プロセスが dlopen する共有ライブラリ内で使用した場合は、必ずしも機能しません。この方法は、下位互換性を維持する目的で提供されており、ほかの目的での使用は推奨されません。
どんな言語を使用している場合も、プログラムを -lcollector とリンクしないでください。リンクした場合、コレクタが予期しない動作をすることがあります。
Fortran API の libfcollector.h ファイルには、ライブラリに対する Fortran インタフェースが定義されています。このライブラリを使用するには、アプリケーションを -lcollectorAPI にリンクする必要があります。このライブラリには、下位互換性を維持するため、-lfcollector というもう 1 つの名前も用意されています。動的関数とスレッドによる呼び出しの一時停止と再開を除けば、Fortran API は C/C++ API と同じ機能を提供します。
Fortran の場合、API 関数を使用するには、次の文を挿入します。
include "libfcollector.h" |
どんな言語を使用している場合も、プログラムを -lcollector とリンクしないでください。リンクした場合、コレクタが予期しない動作をすることがあります。
次の文を使用して、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 つのマスタースレッドで、それ自体を含むすべてのスレッドのすべての呼び出しを行う方法と、各スレッドで自身のみの呼び出しを行う方法があります。その他の使用方法では、結果が予測できないものになる可能性があります。
ここでは、データ収集に関係する API 関数について説明します。
C と C++: collector_sample(char *name)
Fortran: collector_sample(string name)
Java: CollectorAPI.sample(String name)
標本パケットを記録し、その標本に指定された名前または文字列をラベルとして付けます。ラベルは、「パフォーマンスアナライザ」の「イベント」タブで表示されます。Fortran の引数 string の型は、character です。
標本ポイントに含まれるデータは、プロセスに関するものであり、個々のスレッドに関するものではありません。マルチスレッドアプリケーションの場合、collector_sample() API 関数は、標本の記録中に別の呼び出しが行われても、1 つの標本だけが書き込まれるようにします。記録される標本の数は、呼び出しを行うスレッドの数よりも少なくなります。
パフォーマンスアナライザは、別々のメカニズムによって記録された標本同士を区別しません。API 呼び出しによって記録された標本だけを見たい場合には、パフォーマンスデータの記録時にほかのあらゆる標本モードを停止します。
C、C++、Fortran: collector_pause()
Java: CollectorAPI.pause()
実験へのイベント固有データの書き込みを停止します。実験はオープン状態のままであり、大域データの書き込みは続けられます。有効な実験がない場合やデータの記録がすでに停止されている場合には、呼び出しは無視されます。この関数は、たとえすべてのイベント固有データの書き込みが collector_thread_resume() 関数によって特定のスレッドに対して有効にされていたとしても、その書き込みを停止します。
C、C++、Fortran: collector_resume()
Java: CollectorAPI.resume()
collector_pause() を呼び出したあとに、実験へのイベント固有データの書き込みを再開します。有効な実験がない場合やデータの記録が有効である場合には、呼び出しは無視されます。
C と C++ のみ: collector_thread_pause(unsigned int t)
Java: CollectorAPI.threadPause(Thread t)
引数リストで指定したスレッドから実験へのイベント固有データの書き込みを停止します。引数 t は、C/C++ プログラムの場合は POSIX スレッド識別子、Java プログラムの場合は Java スレッドです。実験がすでに終了したか、実験が有効でないか、あるいは、そのスレッドに対するデータの書き込みがすでにオフになっている場合、呼び出しは無視されます。この関数は、たとえデータの書き込みが大域的に有効でも、指定したスレッドからのデータの書き込みを停止します。デフォルトでは、個々のスレッドのデータの記録がオンに設定されます。
C と C++ のみ: collector_thread_resume(unsigned int t)
Java: CollectorAPI.threadResume(Thread t)
引数リストで指定したスレッドから実験へのイベント固有データの書き込みを再開します。引数 t は、C/C++ プログラムの場合は POSIX スレッド識別子、Java プログラムの場合は Java スレッドです。実験がすでに終了したか、実験が有効でないか、あるいは、そのスレッドに対するデータの書き込みがすでにオンになっている場合、呼び出しは無視されます。データは、データの書き込みが大域的に有効にされ、スレッドに対して有効にされているときのみ、実験に書き込まれます。
C、C++、Fortran: collector_terminate_expt()
Java: CollectorAPI.terminate
データを収集している実験を終了します。 以降、データの収集は行われませんが、プログラムは正常に動作を続けます。有効な実験がない場合は、呼び出しは無視されます。
使用している 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 関数について説明します。
実験への記録のため、動的にコンパイルされた関数に関する情報をコレクタに渡します。パラメータリストを次の表に示します。
表 3–1 collector_func_load() のパラメータリスト
パラメータ |
定義 |
---|---|
name |
パフォーマンスツールで使用する、動的にコンパイルされた関数の名前。実際の関数名でなくてもかまいません。この名前は関数の通常の命名規則に従っている必要はありませんが、空白文字や引用符は含めないようにします。 |
alias |
関数の説明に使用する任意の文字列。NULL を使用できます。この文字列が解釈の対象となることはありません。 空白文字を含めることができます。アナライザの「概要」タブに表示されます。何の関数であるか、またはなぜ関数が動的に構築されたかを示すために使用できます。 |
sourcename |
関数の構築元であるソースファイルのパス。NULL を使用できます。このソースファイルは、注釈付きソースリストに使用されます。 |
vaddr |
関数が読み込まれたアドレス。 |
size |
バイト数による関数のサイズ。 |
lntsize |
行番号テーブルのエントリの数を示すカウント。行番号情報がない場合には、ゼロとなります。 |
lntable |
lntsize エントリが入っているテーブル。各エントリは、整数対です。第 1 整数はオフセット、第 2 整数は行番号です。あるエントリのオフセットと次のエントリのオフセットとの間の命令はすべて、最初のエントリの行番号に対応します。オフセットは数字の昇順にする必要があります。 行番号の順序は任意です。lntable が NULL である場合、関数のソースリストは利用できませんが、逆アセンブリリストは利用できます。 |
アドレス vaddr にある動的関数が読み込み解除されたことをコレクタに通知します。
ここでは、ハードウェア、オペレーティングシステム、プログラムの実行方法、またはコレクタそのものによって課されるデータ収集の制限事項について説明します。
異なる種類のデータの同時収集に対する制限はありません。すなわち、どのようなデータの種類でも、ほかのデータの種類と同時に収集できます。
プロファイル間隔の最小値とプロファイルに使用する時間の分解能は、特定のオペレーティング環境により異なります。最大値は 1 秒です。プロファイル間隔の値は、時間の分解能のもっとも近い倍数に切り捨てられます。最小値および最大値と時間の分解能を検索するには、引数を付けずに collect コマンドを入力します。
時間ベースのプロファイルでは、SIGPROF シグナルがターゲットに送られたときにデータが記録されます。それによってシグナルを処理するための実行時間の拡大が発生し、呼び出しスタックが展開されます。呼び出しスタックが深く、シグナルが頻繁なほど、実行時間の拡大は大きくなります。一定の範囲までは、時間ベースのプロファイルにより、ある程度の実行時間の拡大が生じますが、これはもっとも深いスタックで実行するプログラムの各部分の実行時間の拡大が大きくなることから生まれます。
可能な場合、デフォルト値は正確なミリ秒数でなく、システムクロックとの相関を回避するために、正確な数値と多少異なる値 (たとえば、10.007ms または 0.997ms など) に設定されます。システムクロックとの相関はデータのひずみをもたらす場合もあります。SPARC プラットフォームでは、同じ方法でカスタム値を設定してください (Linux プラットフォーム上では不可能)。
コレクタライブラリ libcollector.so が事前読み込みされていないかぎり、すでに稼働中のプログラムからはトレースデータを収集できません。詳細は、「動作中のプロセスからのトレースデータの収集」を参照してください。
データのトレースは、トレースされるイベント数に比例して実行時間を拡大させます。時間ベースのプロファイルを同時に行うと、イベントのトレースに起因する実行時間の拡大により、時間データにひずみが生じます。
ハードウェアカウンタオーバーフローのプロファイルには、次のような制限があります。
ハードウェアカウンタオーバーフローデータの収集を行えるのは、ハードウェアカウンタが用意されていてオーバーフロープロファイルをサポートしているプロセッサにおいてだけです。その他のシステムでは、ハードウェアカウンタオーバーフローのプロファイルは行えません。UltraSPARC® III プロセッサファミリより前の UltraSPARC プロセッサは、ハードウェアカウンタオーバーフローのプロファイルをサポートしません。
cpustat(1) が動作しているシステムで、ハードウェアカウンタのオーバーフローデータを収集することはできません。 これは、cpustat がすべてのカウンタを制御しており、ユーザープロセスがカウンタを利用できないためです。データ収集中に cpustat を起動すると、ハードウェアカウンタオーバーフローのプロファイルは終了され、実験にエラーが記録されます。
ハードウェアカウンタオーバーフローのプロファイルを行う場合、独自のコードで libcpc(3) を使用してハードウェアカウンタを使用することはできません。コレクタは libcpc ライブラリ関数に割り込み、コレクタからの呼び出しではなかった場合、-1 の戻り値で復帰します。ハードウェアカウンタへのアクセスの取得に失敗した場合に正常に機能するようにプログラムをコーディングする必要があります。このようにコーディングしなかった場合、ハードウェアカウンタのプロファイル時に、またはルートがカウンタを使用するシステム全体のツールを呼び出した場合にプログラムが失敗します。
dbx をプロセスに接続することによって、ハードウェアカウンタライブラリを使用している実行中プログラムのハードウェアカウンタデータを収集しようとすると、実験が壊れることがあります。
使用可能なすべてのカウンタの一覧を表示するには、引数を指定せずに collect コマンドを実行します。
ハードウェアカウンタのプロファイルでは、SIGEMT がターゲットへ送られたときにデータが記録されます。それによってシグナルを処理するための実行時間の拡大が発生し、呼び出しスタックが展開されます。時間ベースのプロファイルと違い、ハードウェアカウンタによっては、プログラムのさまざまな部分がその他の部分より高速にイベントを生成する場合があり、そのコード部分に実行時間の拡大が生じます。そのようなイベントを非常に高速に生成するプログラムの一部で大きなひずみが生じる場合があります。同様に、あるスレッドでは、ほかのスレッドと不均等にイベントが生成されるものがあります。
派生プロセスに関するデータを収集するには、いくつかの制限事項があります。
コレクタでの派生プロセスすべてについてデータを収集するには、次のいずれかのオプションとともに collect コマンドを使用する必要があります。
-F on オプションを使用すると、fork とそのバリアント、および exec とそのバリアントへの呼び出しについて、自動的にデータを収集できます。
-F all オプションを使用すると、コレクタは、system、popen、および sh の呼び出しに起因するものを含むすべての派生プロセスをたどります。
-F '=regexp' オプションを使用すると、名前または系統が指定した正規表現と一致するすべての派生プロセスに関するデータを収集できます。
-F オプションの詳細については、「実験制御オプション」を参照してください。
Java プログラムに関するデータは収集可能ですが、次の制限事項があります。
1.5.0_03 か、それ以降のバージョンの Java 2 Platform Standard Edition (J2SE) を使用してください。デフォルトでは、collect コマンドは Sun Studio インストーラによって J2SE がインストールされたパス (ある場合) を使用します。JDK_HOME 環境変数または JAVA_PATH 環境変数を設定すると、このデフォルトパスをオーバーライドできます。コレクタはこれらの環境変数で検出した java のバージョンが ELF 実行可能ファイルであるかどうかを確認し、ELF 実行可能ファイルでない場合には、使用した環境変数と試したフルパス名を示すエラーメッセージを出力します。
データの収集には、collect コマンドを使用する必要があります。dbx collector サブコマンドや IDE のデータ収集機能は使用できません。
JVM ソフトウェアを実行する派生プロセスを作成するアプリケーションはプロファイルできません。
64 ビットの JVM ソフトウェアを使用するには、-j on フラグを使用し、64 ビット JVM ソフトウェアをターゲットとして指定する必要があります。64 ビット JVM ソフトウェアを使用してデータを収集するのに、java -d64 を使用しないでください。これを使用すると、データは収集されません。
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(1) のマニュアルページを参照)。collect コマンド行ツールのデータ収集時のオーバーヘッドは dbx よりも小さいため、ほかの方法よりもこの方法の方が優れていることがあります。
パフォーマンスアナライザでパフォーマンスツールにある「収集」ダイアログを使用する (パフォーマンスアナライザのオンラインヘルプの「パフォーマンスツールの「収集」ウィンドウからのパフォーマンスデータの収集」を参照)。
デバッガの「コレクタ」ダイアログを使用する (パフォーマンスアナライザのオンラインヘルプの「デバッガによるパフォーマンスデータの収集」を参照)。
dbx コマンド行から collector コマンドを使用する (「dbx collector サブコマンドによるデータの収集」および IDE にある「デバッグ」オンラインヘルプの「collector コマンド」を参照)。
次のデータ収集機能は、パフォーマンスツールの「収集」ダイアログボックスと collect コマンドでのみ利用できます。
Java プログラムに関するデータの収集。IDE にあるデバッガの「コレクタ」ダイアログまたは dbx の collector コマンドで Java プログラムに関するデータの収集を試みた場合、実際に収集される情報は、Java プログラムではなく JVM ソフトウェアに関する情報です。
派生プロセスに関するデータの自動収集。
collect コマンドを使用してコマンド行からコレクタを実行するには、次のコマンドを使用します。
% collect collect-options program program-arguments |
ここで、collect-options は collect コマンドのオプション、program はデータの収集対象のプログラム名、program-arguments はプログラムの引数です。
collect-options を指定しなかった場合は、デフォルトで時間ベースのプロファイルが有効になり、プロファイル間隔は約 10 ミリ秒になります。
コマンドオプションの一覧とプロファイルに使用可能なハードウェアカウンタ名の一覧を表示するには、引数を指定せずに collect コマンドを実行します。
% collect |
ハードウェアカウンタの一覧については、「ハードウェアカウンタオーバーフローのプロファイルデータ」を参照してください。「ハードウェアカウンタオーバーフローのプロファイルに関する制限事項」も参照してください。
データ収集のオプションは、どのような種類のデータを収集するのかを制御します。データの種類については、「コレクタが収集するデータの内容」を参照してください。
データ収集オプションを指定しなかった場合、デフォルトは -p on で、デフォルトのプロファイル間隔 (約 10 ミリ秒) で時間ベースのプロファイルが行われます。このデフォルト設定は、-h オプションを使用することによってのみ無効にできます。
時間ベースのプロファイルを明示的に無効とし、すべてのトレースとハードウェアカウンタオーバーフロープロファイルを有効にしなかった場合、collect コマンドは警告メッセージを出力し、大域データだけを収集します。
時間ベースのプロファイルデータを収集します。option には次のいずれかの値を指定できます。
off– 時間ベースのプロファイルを無効にします。
on– デフォルトのプロファイル間隔 (約 10 ミリ秒) で時間ベースのプロファイルを有効にします。
lo[w]– 低分解能プロファイル間隔 (約 100 ミリ秒) で時間ベースのプロファイルを有効にします。
hi[gh]– 高分解能プロファイル間隔 (約 1 ミリ秒) で時間ベースのプロファイルを有効にします。高分解能のプロファイルについては、「時間ベースのプロファイルに関する制限事項」を参照してください。
[+]value– 時間ベースのプロファイルを有効にし、プロファイル間隔を value に設定します。 value のデフォルトの単位はミリ秒です。value は、整数または浮動小数点数として指定できます。オプションとして、数値の後ろに接尾辞 m を付けてミリ秒単位を選択するか、u を付けてマイクロ秒単位を選択することができます。プロファイル間隔は、時間の分解能の倍数である必要があります。時間の分解能値よりも大きな値であっても倍数でない場合は、端数が切り捨てられます。時間の分解能値よりも小さな値の場合は、警告メッセージが出力され、時間の分解能に設定されます。
SPARC プラットフォームでは、ハードウェアカウンタのプロファイルと同様に、値の前に + 記号と付けて時間ベースのデータ空間プロファイリングを有効にできます。
collect コマンドは、デフォルトで時間ベースのプロファイルデータを収集します。
ハードウェアカウンタオーバーフローのプロファイルデータを収集します。カウンタ定義の数はプロセッサに依存します。 このオプションは、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 には、次のいずれかを指定できます。
既知の (別名を持つ) カウンタ名
cputrack(1) によって使用されるような raw (内部) 名。イベントレジスタのいずれかをカウンタに使用可能な場合は、内部名に /0 または /1 を付加することによって指定できます。
複数のカウンタを指定する場合、それらのカウンタは異なるレジスタを使用する必要があります。同じレジスタが指定された場合、collect コマンドはエラーメッセージを出力して終了します。どちらのレジスタでもカウントできるカウンタもあります。
使用可能なカウンタの一覧を表示するには、引数を指定せずに collect コマンドを端末ウィンドウに入力します。「ハードウェアカウンタのリスト」に、カウンタの一覧があります。
ハードウェアカウンタがメモリーアクセスに関連するイベントをカウントする場合、カウンタ名の前に + 記号を付けて、カウンタのオーバーフローを発生させた命令の実際のプログラムカウンタアドレス (PC) の検索をオンにすることができます。バックトラッキングは SPARC プロセッサ上で、load、store、load-store のいずれかのタイプのカウンタでのみ機能します。検索が成功すると、仮想 PC、物理 PC、および参照された有効アドレスがイベントデータパケットに格納されます。
一部のプロセッサでは、属性オプションをハードウェアカウンタへ関連付けることができます。 プロセッサが属性オプションをサポートしている場合は、collect コマンドを引数リストなしで実行すると、属性名を含むカウンタ定義が一覧表示されます。属性値は、10 進数または 16 進数形式で指定できます。
間隔 (オーバーフロー値) は、ハードウェアカウンタがオーバーフローしてオーバーフローイベントが記録されたときにカウントされたイベント数です。間隔は、次のいずれかに設定できます。
on または NULL 文字列 – デフォルトのオーバーフロー値。これは、collect を引数なしで入力することによって判別できます。
hi[gh]– 選択したカウンタの高分解能値。これは、デフォルトのオーバーフロー値の約 10 分の 1 の値です。旧バージョンのソフトウェアとの互換を図るため、h の省略形もサポートされています。
lo[w]– 選択したカウンタの低分解能値。これは、デフォルトのオーバーフロー値より約 10 倍長い値です。
interval– 特定のオーバーフロー値。これは正の整数である必要がありますが、10 進数と 16 進数のどちらの形式でもかまいません。
デフォルトでは、事前に各カウンタに定義されている通常のしきい値が使用されます。これらの値はカウンタの一覧に表示されます。「ハードウェアカウンタオーバーフローのプロファイルに関する制限事項」も参照してください。
-p オプションを明示的に指定せずに -h オプションを使用すると、時間ベースのプロファイルが無効となります。ハードウェアカウンタデータと時間ベースデータの両方を収集するには、 -h オプションと -p オプションの両方を指定する必要があります。
同期待ちトレースデータを収集します。option には次のいずれかの値を指定できます。
all– しきい値ゼロで同期待ちのトレースを有効にします。このオプションは、すべての同期イベントの記録を強制的に有効にします。
calibrate– 同期待ちのトレースを有効にし、実行時に測定を行うことによってしきい値を設定します。on と同じです。
off– 同期待ちのトレースを無効にします。
on– デフォルトのしきい値 (実行時の測定で値を決定) で同期待ちのトレースを有効にします。calibrate と同じです。
同期待ちのトレースデータは、Java モニターには記録されません。
ヒープトレースデータを収集します。option には次のいずれかの値を指定できます。
on– ヒープの割り当て要求と割り当て解除要求のトレースを有効にします。
off– ヒープのトレースを無効にします。
デフォルトでは、ヒープのトレースは無効です。ヒープトレースは Java プログラムについてはサポートされず、指定するとエラーとして処理されます。
MPI トレースデータを収集します。option には次のいずれかの値を指定できます。
on– MPI 呼び出しのトレースを有効にします。
off– MPI 呼び出しのトレースを無効にします。
デフォルトでは、MPI トレースは無効です。
呼び出しがトレースされる MPI 関数とトレースデータをもとに計算されるメトリックの詳細については、「MPI トレースデータ」を参照してください。
標本パケットを定期的に記録します。option には次のいずれかの値を指定できます。
off– 定期的標本収集を無効にします。
on– デフォルトの標本収集間隔 (1 秒) による定期的な標本収集を有効にします。
デフォルトでは、1 秒間隔による定期的標本収集が有効になります。
カウントデータを記録します。SPARC プロセッサだけが対象です。
この機能を使用するには、Sun Studio 12 用 Add-on Cool Tools に含まれるバイナリインタフェースツール (BIT) が必要です。このツールは、http://cooltools.sunsource.net/ からダウンロードできます。BIT は、SPARC バイナリのパフォーマンスやテストスイートカバレージの測定用ツールです。
option には次のいずれかの値を指定できます。
on– 関数と命令のカウントデータの収集を有効にします。実行可能ファイル、およびその実行可能ファイルが静的にリンクしている共有オブジェクトが -xbinopt=prepare フラグを指定してコンパイルされている場合に、そのデータが記録されます。静的にリンクしていても -xbinopt=prepare フラグを指定してコンパイルされていない共有オブジェクトはデータに含まれません。同様に、動的に開く共有オブジェクトはデータに含まれません。データは、パフォーマンスアナライザの「命令頻度」タブ、または er_print ifreq コマンドで確認できます。
static– ターゲットの実行可能ファイル、および静的にリンクされている共有オブジェクト内のすべての命令が 1 回だけ実行されたという前提で実験を生成します。-c on オプションと同様に、-c static オプションも、実行可能ファイルと共有オブジェクトが -xbinopt=prepare フラグを指定してコンパイルされている必要があります。
スレッドアナライザ用に、データ競合検出またはデッドロック検出のデータを収集します。次のいずれかの値を指定できます。
on – スレッドアナライザのデータ競合検出データを有効にします。
off– スレッドアナライザのデータを無効にします。
all– スレッドアナライザのデータをすべて有効にします。
race- スレッドアナライザのデータ競合検出データを有効にします。
deadlock– デッドロックと潜在的デッドロックのデータを収集します。
dtN– スレッドアナライザの特定のデータの種類を有効にします。データの種類は dt* パラメータで指定します。
collect -r コマンドとスレッドアナライザの詳細については、『Sun Studio 12: Thread Analyzer User’s Guide』および tha.1 のマニュアルページを参照してください。
派生プロセスのデータを記録するかどうかを制御します。option には次のいずれかの値を指定できます。
on– 関数 fork、exec、およびそのバリアントが作成する派生プロセスについてのみ実験を記録します。
all– すべての派生プロセスについて実験を記録します。
off– 派生プロセスに関する実験を記録しません。
= regexp– 名前または系統が指定する正規表現と一致する派生プロセスの実験をすべて記録します。
-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 つ開きます。これらの新しい実験は、次のように、下線、文字、および数字を実験接尾辞に追加することで命名されます。
英字「f」は fork、英字「x」は exec、英字「c」はほかの派生プロセスをそれぞれ表します。
数字は、fork または exec (成功したかどうかに関係なく)、あるいはその他の呼び出しのインデックスです。
たとえば初期プロセスの実験名が 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_print か analyzer にパス名を明示的に指定します。指定するパスには、親の実験名と、親ディレクトリ内の派生実験名を含める必要があります。
たとえば、test.1.er 実験の 3 回目の fork のデータを表示する場合は、次のように指定します。
er_print test.1.er/_f3.er
analyzer test.1.er/_f3.er
もう一つの方法として、関心のある派生の実験の明示的な名前を入れた実験グループファイルを用意する方法もあります。
アナライザで派生プロセスを調べるには、親の実験を読み込んで、「表示」メニューから「データをフィルタ」を選択します。実験のリストは、親の実験のみが選択されて表示されます。これを選択解除し、対象とする派生実験を選択します。
派生プロセスが追跡されている間に親プロセスが終了した場合、派生のデータ収集が継続する可能性があります。それに従って親の実験ディレクトリは拡大を続けます。
ターゲットプログラムが JVM の場合に Java プロファイルを有効にします。option には次のいずれかの値を指定できます。
on – Java HotSpot 仮想マシンによってコンパイルされたメソッドを認識し、Java 呼び出しスタックを記録しようとします。
off – Java HotSpot 仮想マシンによってコンパイルされたメソッドを認識しようとしません。
path – 指定された path にインストールされた JVM についてのプロファイルデータを記録します。
-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 のパスを指定してください。
プロファイリングに使用する JVM に渡す引数を 1 つ指定します。-J オプションを指定し、Java プロファイリングを指定しなかった場合は、エラーが生成され、実験は実行されません。引数は、単一の引数として JVM に渡されます。複数の引数が必要な場合は、-J オプションを使用しないでください。この場合、collect コマンド行で、JVM のパスを明示的に指定し、-j on を使用して JVM のパスのあとに JVM の引数を追加します。
signal というシグナルがプロセスへ送信されたときに標本パケットを記録します。
シグナルは、完全なシグナル名、先頭文字 SIG を省いたシグナル名、またはシグナル番号のいずれの形式でも指定できます。ただし、プログラムが使用するシグナル、または実行を終了するシグナルは指定しないでください。推奨するシグナルは SIGUSR1 および SIGUSR2 です。シグナルは、kill コマンドを使用してプロセスに送信できます。
-l および -y の両方のオプションを使用する場合は、それぞれのオプションに異なるシグナルを使用する必要があります。
プログラムに独自のシグナルハンドラがあるときにこのオプションを使用する場合には、-l で指定するシグナルが、阻止されたり、無視されたりすることなく、確実にコレクタのシグナルハンドラに渡されるようにする必要があります。
シグナルについては、signal(3HEAD) のマニュアルページを参照してください。
データ収集の時間範囲を指定します。
<所要時間> は単数で指定でき、オプションで m または s 接尾辞を付けることができます。これらは、実験を終了する時間が分か秒かを示しています。デフォルトでは、所要時間は秒です。<所要時間> はハイフンで区切られた 2 つの数で指定することもできます。これは、1 つ目の時間が経過するまでデータ収集を停止し、そして、データ収集を始める時間を示しています。2 つ目の時間が経過すると、データ収集が終了されます。2 番目の数値がゼロの場合、最初の一時停止から、プログラムの実行が終了するまでデータが収集されます。実験が終了しても、ターゲットのプロセスは完了するまで実行を続けます。
デバッガがそのプロセスに接続できるように、exec システムコールの終了時にターゲットプロセスを停止したままにします。dbx をプロセスに接続した場合には、dbx コマンドの ignore PROF と ignore EMT を使用して、収集シグナルが確実に collect コマンドに渡されるようにします。
signal というシグナルで、データの記録を制御します。このシグナルがプロセスに送信されると、一時停止状態 (データは記録されない) と記録状態 (データは記録される) が切り替わります。ただし、このスイッチの状態に関係なく、標本ポイントは常に記録されます。
シグナルは、完全なシグナル名、先頭文字 SIG を省いたシグナル名、またはシグナル番号のいずれの形式でも指定できます。ただし、プログラムが使用するシグナル、または実行を終了するシグナルは指定しないでください。推奨するシグナルは SIGUSR1 および SIGUSR2 です。シグナルは、kill(1) コマンドを使用してプロセスに送信できます。
-l および -y の両方のオプションを使用する場合は、それぞれのオプションに異なるシグナルを使用する必要があります。
-y オプションに r 引数 (省略可能) を指定した場合、コレクタは記録状態で起動します。 それ以外の場合は、一時停止状態でコレクタが起動します。-y オプションを指定しなかった場合は、記録状態で起動します。
プログラムに独自のシグナルハンドラがあるときにこのオプションを使用する場合には、-y で指定するシグナルが、阻止されたり、無視されたりすることなく、確実にコレクタのシグナルハンドラに渡されるようにする必要があります。
シグナルについては、signal(3HEAD) のマニュアルページを参照してください。
記録する実験の名前として experiment_name を使用します。experiment_name 文字列は「.er」で終わる必要があり、そうでない場合、collect ユーティリティーはエラーメッセージを出力して終了します。
directory-name というディレクトリに実験を格納します。このオプションは個別の実験にのみ適用され、実験グループには適用されません。ディレクトリが存在しない場合、collect ユーティリティーはエラーメッセージを出力して終了します。-g オプションでグループが指定されている場合は、グループファイルも directory-name へ書き込まれます。
実験を group-name という実験グループに含めます。group-name の末尾が .erg でない場合、collect ユーティリティーはエラーメッセージを出力して終了します。グループが存在する場合は、グループに実験が追加されます。group-name が絶対パスでない場合、-d でディレクトリを指定したとすれば、実験グループはディレクトリ directory-name に設定され、それ以外は現在のディレクトリに設定されます。
ターゲットプロセスで使用されるロードオブジェクトを、記録済み実験に保管またはコピーするかどうかを管理します。オプションには、次のいずれかの値を指定できます。
off– ロードオブジェクトを実験に保管しません。
on– ロードオブジェクトを実験に保管します。
copy– ロードオブジェクトをコピーして実験に保管します。
実験データが記録されたマシンとは異なるマシンに実験データをコピーするか、異なるマシンから実験データを読み取る場合は、 - A copy を指定します。このオプションを使用しても、ソースファイルまたはオブジェクトファイルは実験にコピーされません。実験データのコピー先のマシン上で、これらのファイルにアクセスできるかどうかを確認してください。
記録するプロファイルデータの量を size メガバイトに制限します。この制限は、時間ベースのプロファイルデータ、ハードウェアカウンタオーバーフローのプロファイルデータ、および同期待ちのトレースデータの合計に適用されますが、標本ポイントには適用されません。この制限値は概数にすぎないので、この値を超えることは可能です。
制限に達すると、それ以上のプロファイルデータは記録されませんが、ターゲットプロセスが終了するまで実験はオープン状態となります。定期的な標本収集が有効である場合、標本ポイントの書き込みが継続されます。
記録されるデータのデフォルトの制限値は 2000M バイトです。この制限値が選択されたのは、2G バイトを超えるデータの実験をパフォーマンスアナライザが処理することができないためです。制限を外すには、size を unlimited または none に設定します。
collect 自体の全出力を指定された file に付加しますが、生成されたターゲットからの出力はリダイレクトしません。ファイルが /dev/null に設定されている場合は、エラーメッセージを含む collect の全出力が抑制されます。
実験の notes ファイルにコメントを追加します。最大 10 個の -C オプションを指定できます。notes ファイルの内容は、実験のヘッダーの先頭に付加されます。
ターゲットを実行しませんが、ターゲットが実行されれば生成されたはずの実験の詳細を出力します。このオプションは「ドライラン」オプションです。
パフォーマンスアナライザの Readme のテキストバージョンを端末ウィンドウに表示します。readme が見つからない場合は、警告が出力されます。これ以降に指定した引数は検査されず、これ以外の処理は行われません。
collect コマンドの現在のバージョンを表示します。これ以降に指定した引数は検査されず、これ以外の処理は行われません。
collect コマンドの現在のバージョンと、実行中の実験に関する詳細情報を表示します。
Solaris OS では、collect ユーティリティーで -P pid オプションを使用して、指定する PID のプロセスに接続し、そのプロセスのデータを収集できます。collect コマンドのその他のオプションは dbx 用のスクリプトに変換され、そのスクリプトを実行してデータが収集されます。時間ベースのプロファイルデータ (-p オプション) とハードウェアカウンタオーバーフローのプロファイルデータ (-h オプション) だけを収集できます。トレースデータはサポートされていません。
-p オプションを明示的に指定せずに -h オプションを使用すると、時間ベースのプロファイルが無効となります。ハードウェアカウンタデータと時間ベースデータの両方を収集するには、 -h オプションと -p オプションの両方を指定する必要があります。
プログラムのプロセス ID (PID) を調べます。
コマンド行からプログラムを起動してバックグラウンドで実行している場合は、シェルによってその PID が標準出力に出力されます。その他の場合は、次のコマンドを使用し、プログラムの PID を調べることができます。
% ps -ef | grep program-name |
collect コマンドを使用してプロセスのデータの収集を有効にし、オプションのパラメータを適宜設定します。
% collect -P pid collect-options |
コレクタのオプションについては、「データ収集オプション」を参照してください。時間ベースのプロファイルについては、「-p option」を参照してください。ハードウェアカウンタオーバーフローのプロファイルについては、-h optionを参照してください。
この節では、dbx からコレクタを実行する方法、また dbx 内の collector コマンドで使用できる各サブコマンドについて説明します。
% dbx program |
collector コマンドを使用してデータの収集を有効にし、データの種類を選択し、オプションのパラメータを適宜設定します。
(dbx) collector subcommand |
利用可能な collector サブコマンドの一覧を表示するには、次のコマンドを使用します。
(dbx) help collector |
サブコマンドごとに collector コマンドを 1 つ使用する必要があります。
使用する dbx のオプションを設定し、プログラムを実行します。
指定したサブコマンドに誤りがある場合は、警告メッセージが出力され、サブコマンドは無視されます。このあとに、collector の全サブコマンドをまとめます。
ここでは、コレクタが収集するデータの種類を制御するサブコマンドをまとめています。実験がアクティブな場合は、警告メッセージが出力され、サブコマンドは無視されます。
時間ベースのプロファイルデータの収集を制御します。option には次のいずれかの値を指定できます。
on– デフォルトのプロファイル間隔 (10 ミリ秒) で時間ベースのプロファイルを有効にします。
off– 時間ベースのプロファイルを無効にします。
timer interval– プロファイル間隔を設定します。interval には次のいずれかの値を指定できます。
on– デフォルトのプロファイル間隔 (約 10 ミリ秒) を使用します。
lo[w]– 低分解能のプロファイル間隔 (約 100 ミリ秒) を使用します。
hi[gh]– 高分解能のプロファイル間隔 (約 1 ミリ秒) を使用します。高分解能のプロファイルについては、「時間ベースのプロファイルに関する制限事項」を参照してください。
value– プロファイル間隔を value に設定します。value のデフォルトの単位はミリ秒です。value は、整数または浮動小数点数として指定できます。オプションとして、数値の後ろに接尾辞 m を付けてミリ秒単位を選択するか、u を付けてマイクロ秒単位を選択することができます。プロファイル間隔は、時間の分解能の倍数である必要があります。時間の分解能値よりも大きな値であっても倍数でない場合は、端数が切り捨てられます。時間の分解能値よりも小さな値の場合は、時間の分解能に設定されます。どちらの場合にも、警告メッセージが表示されます。
デフォルトの設定は約 10 ミリ秒です。
デフォルトでは、hwprofile サブコマンドを使用してハードウェアカウンタオーバーフローのプロファイルデータ収集が有効になっていないかぎり、コレクタは時間ベースのプロファイルデータを収集します。
ハードウェアカウンタオーバーフローのプロファイルデータの収集を制御します。ハードウェアカウンタオーバーフローのプロファイル機能をサポートしていないシステム上でこの機能を有効にしようとすると、dbx から警告メッセージが返され、コマンドは無視されます。option には次のいずれかの値を指定できます。
on– ハードウェアカウンタオーバーフローのプロファイルを有効にします。デフォルトでは、通常のオーバーフロー値で cycles カウンタのデータが収集されます。
off– ハードウェアカウンタオーバーフローのプロファイルを無効にします。
list– 使用可能なカウンタの一覧を返します。一覧については、「ハードウェアカウンタのリスト」を参照してください。ハードウェアカウンタオーバーフローのプロファイル機能がシステムでサポートされていない場合は、dbx から警告メッセージが返されます。
counter counter_definition... [, counter_definition ]– カウンタ定義には、プロセッサがハードウェアカウンタの属性をサポートしているかどうかに応じて、次のいずれかの形式を使用できます。
[+] counter_name[/ register_number][,interval ]
[+]counter_name[~ attribute_1=value_1]...[~attribute_n =value_n][/ register_number][,interval ]
ハードウェアカウンタの name を選択し、そのオーバーフロー値を interval に設定します。オプションとして、追加のハードウェアカウンタ名を選択し、それらのオーバーフロー値を指定された間隔に設定します。オーバーフロー値は次のいずれかです。
on または NULL 文字列 – デフォルトのオーバーフロー値。これは、collect を引数なしで入力することによって判別できます。
hi[gh]– 選択したカウンタの高分解能値。これは、デフォルトのオーバーフロー値の約 10 分の 1 の値です。旧バージョンのソフトウェアとの互換を図るため、h の省略形もサポートされています。
lo[w]– 選択したカウンタの低分解能値。これは、デフォルトのオーバーフロー値より約 10 倍長い値です。
interval– 特定のオーバーフロー値。これは正の整数でなければなりませんが、10 進数と 16 進数のどちらの形式でもかまいません。
複数のカウンタを指定する場合、それらのカウンタは異なるレジスタを使用する必要があります。使用するレジスタが同じである場合は警告メッセージが出力され、コマンドは無視されます。
ハードウェアカウンタがメモリーアクセスに関連するイベントをカウントする場合、カウンタ名の前に + 記号を付けて、カウンタのオーバーフローを発生させた命令の実際の PC の検索をオンにすることができます。検索が成功すると、PC と参照された有効アドレスがイベントデータパケットに格納されます。
デフォルトでは、コレクタは、ハードウェアカウンタのオーバーフロープロファイルデータを収集しません。ハードウェアカウンタオーバーフローのプロファイルが有効になっていて profile コマンドが指定されていない場合、時間ベースのプロファイルは無効となります。
「ハードウェアカウンタオーバーフローのプロファイルに関する制限事項」も参照してください。
同期待ちトレースデータの収集を制御します。option には次のいずれかの値を指定できます。
on– デフォルトのしきい値で同期待ちトレースを有効にします。
off– 同期待ちのトレースを無効にします。
threshold value– 記録する最小同期遅延のしきい値を設定します。value には次のいずれかの値を指定できます。
ヒープトレースデータの収集を制御します。option には次のいずれかの値を指定できます。
on– ヒープのトレースを有効にします。
off– ヒープのトレースを無効にします。
デフォルトでは、コレクタはヒープのトレースデータを収集しません。
MPI トレースデータの収集を制御します。option には次のいずれかの値を指定できます。
on– MPI 呼び出しのトレースを有効にします。
off– MPI 呼び出しのトレースを無効にします。
デフォルトでは、コレクタは MPI のトレースデータを収集しません。
スレッドアナライザ用に、データ競合検出またはデッドロック検出のデータを収集します。次のいずれかの値を指定できます。
on – スレッドアナライザのデータ競合検出データを有効にします。
off– スレッドアナライザのデータを無効にします。
all– スレッドアナライザのデータをすべて有効にします。
race – スレッドアナライザのデータ競合検出データを有効にします。
deadlock– デッドロックと潜在的デッドロックのデータを収集します。
dtN– スレッドアナライザの特定のデータの種類を有効にします。データの種類は dt* パラメータで指定します。
スレッドアナライザについては、『Sun Studio 12: Thread Analyzer User’s Guide』および tha.1 のマニュアルページを参照してください。
標本収集モードを制御します。option には次のいずれかの値を指定できます。
periodic– 定期的な標本収集を有効にします。
manual– 定期的な標本収集を無効にします。手動の標本収集は有効のままです。
デフォルトでは、標本収集間隔 value が 1 秒での定期的な標本収集が有効となります。
dbx がターゲットプロセスを停止したときに、標本を記録するかどうかを制御します。キーワードの意味は、次のとおりです。
on– dbx がターゲットプロセスを停止するたびに標本が記録されます。
off– dbx がターゲットプロセスを停止したときの標本が記録されません。
デフォルトでは、dbx がターゲットプロセスを停止したとき、標本が記録されます。
データの収集を無効にします。プロセスが動作中でデータを収集中の場合は、その実験が終了し、データ収集が無効になります。プロセスが動作中でデータ収集が無効になっている場合、警告が出され、このサブコマンドは無視されます。プロセスが動作していない場合は、以降の実行のデータ収集が無効になります。
データの収集を有効にします。プロセスが動作していてデータ収集が無効であった場合、データ収集が有効になって新しい実験が開始されます。プロセスが動作中でデータ収集が有効になっている場合、警告が出され、このサブコマンドは無視されます。プロセスが動作していない場合は、以降の実行のデータ収集が有効になります。
プロセスの動作中、データ収集は何回でも有効にしたり、無効にしたりできます。データ収集を有効にするたびに、新しい実験が作成されます。
実験を開いたまま、データの収集を一時停止します。コレクタが一時停止している間、標本ポイントは記録されません。標本は一時停止の前に生成され、再開直後に別の標本が生成されます。データの収集がすでに一時停止されている場合、このサブコマンドは無視されます。
pause が実行されたあとに、データの収集を再開します。データ収集中は、このサブコマンドは無視されます。
name のラベルが付いた標本パケットを記録します。ラベルは、パフォーマンスアナライザの「イベント」タブで表示されます。
次のサブコマンドは、実験の格納オプションを指定します。実験がアクティブな場合は、警告メッセージが出力され、サブコマンドは無視されます。
実験を保管するためのモードを設定します。 mode には次のいずれかの値を指定できます。
on– ロードオブジェクトの通常の保管に設定します。
off– ロードオブジェクトを保管しません。
copy– 通常の保管のほかにロードオブジェクトを実験にコピーします。
異なるマシンに実験を移動するか、別のマシンから実験を読み取る場合は、ロードオブジェクトのコピーを有効にする必要があります。実験がアクティブな場合、警告が出され、このコマンドは無視されます。このコマンドを使用しても、ソースファイルまたはオブジェクトファイルは実験にコピーされません。
記録するプロファイルデータの量を value メガバイトに制限します。この制限は、時間ベースのプロファイルデータ、ハードウェアカウンタオーバーフローのプロファイルデータ、および同期待ちのトレースデータの合計に適用されますが、標本ポイントには適用されません。この制限値は概数にすぎないので、この値を超えることは可能です。
制限に達すると、それ以上のプロファイルデータは記録されませんが、実験はオープンのままで標本ポイントの記録は継続します。
記録されるデータのデフォルトの制限値は 2000M バイトです。この制限値が選択されたのは、2G バイトを超えるデータの実験をパフォーマンスアナライザが処理することができないためです。制限を外すには、value を unlimited または none に設定します。
実験の格納先を指定します。 実験がアクティブな場合、警告が出され、このコマンドは無視されます。option には次のいずれかの値を指定できます。
directory directory-name– 実験と実験グループの格納先のディレクトリを指定します。指定したディレクトリが存在しない場合、警告が出され、このサブコマンドは無視されます。
experiment experiment-name– 実験の名前を設定します。指定した実験名の末尾が .er でない場合、警告が出され、このサブコマンドは無視されます。実験名とコレクタにおける実験名の取り扱いについての詳細は、「収集データの格納場所」を参照してください。
group group-name– 実験グループの名前を設定します。指定したグループ名の末尾が .erg でない場合、警告が出され、このサブコマンドは無視されます。グループがすでに存在する場合は、実験がグループに追加されます。ディレクトリ名が store directory サブコマンドで設定され、グループ名が絶対パスでない場合、グループ名の前にディレクトリ名が付きます。
すべてのコレクタ制御の、現在の設定を表示します。
コレクタでは、動作中のプロセスからデータを収集できます。プロセスがすでに dbx の制御下にある場合は、プロセスを一時停止し、これまでに説明した方法を使用してデータ収集を有効にすることができます。
プロセスが dbx の制御下にない場合は、collect –P pid コマンドを使用して、実行中のプロセスからデータを収集できます。詳細は、「collect ユーティリティーによる動作中のプロセスからのデータの収集」を参照してください。プロセスに dbx を接続し、パフォーマンスデータを収集し、プロセスから切り離して、プロセスの実行を継続することもできます。選択した派生プロセスのパフォーマンスデータを収集するには、各プロセスに dbx を接続する必要があります。
プログラムのプロセス ID (PID) を調べます。
コマンド行からプログラムを起動していて、バックグラウンドで実行している場合は、シェルによってその PID が標準出力に出力されます。その他の場合は、次のように入力してプログラムの PID を調べることができます。
% ps -ef | grep program-name |
プロセスに接続します。
dbx から、次のように入力します。
(dbx) attach program-name pid |
dbx をまだ実行していない場合は、次のように入力します。
% dbx program-name pid |
実行中のプロセスに接続すると、そのプロセスが一時停止します。
プロセスへの接続については、『Sun Studio 12: Debugging a Program With dbx』を参照してください。
データの収集を開始します。
dbx から、collector コマンドを使用してデータ収集パラメータを設定し、cont コマンドを使用してプロセスを再開します。
プロセスから切り離します。
データの収集を完了したら、プログラムを一時停止し、dbx からプロセスを切り離します。
dbx から、次のように入力します。
(dbx) detach |
トレースデータを収集する場合は、プログラムを実行する前に、コレクタライブラリの libcollector.so を事前に読み込んでおく必要があります。 これは、このライブラリによって、データの収集を可能にする実関数にラッパーが提供されるためです。また、コレクタは、ほかのシステムライブラリの呼び出しにもラッパー関数を追加し、それによって完全なパフォーマンスデータを確保できます。コレクタライブラリを事前に読み込まなかった場合、ラッパー関数は挿入できません。コレクタがシステムライブラリ関数に割り込む方法の詳細については、「システムライブラリの使用」を参照してください。
libcollector.so を事前に読み込むには、次の表に示すように、環境変数を使用してライブラリ名とライブラリパスの両方を設定する必要があります。ライブラリ名を設定するには、環境変数 LD_PRELOAD を使用します。ライブラリのパスを設定するには、環境変数 LD_LIBRARY_PATH、LD_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_PRELOAD と LD_LIBRARY_PATH の設定を削除し、同じシェルから起動されるほかのプログラムが設定の影響を受けないようにしてください。
すでに実行中の MPI プログラムからデータを収集する場合は、プロセスごとに 1 つの dbx インスタンスを接続し、それらのプロセスごとにコレクタを有効にする必要があります。MPI ジョブのプロセスに dbx を接続すると、各プロセスが停止され、別々の時間に再起動されます。この時間差によって MPI プロセス間のインタラクションに変化が生じ、収集するパフォーマンスデータに影響を及ぼす可能性があります。この問題の影響を最小限にするための 1 つの方法に、 pstop(1) コマンドを使用してすべてのプロセスを停止することがあります。ただし、プロセスを一度 dbx に接続すると、dbx からそれらのプロセスを再開する必要があり、そのときに時間的な遅延が発生して、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 ランクに基づき、標準形式の experiment.m.er で実験名を作成します。 この場合の m は MPI ランクです。experiment は、実験グループが指定された場合は実験グループ名で、それ以外の場合は test になります。共通ファイルシステムまたはローカルファイルシステムのどちらを使用しているかに関係なく、実験名は一意です。つまり、ローカルファイルシステムを使用して実験を記録し、それらのファイルを共通のファイルシステムにコピーして実験グループファイルを再構築する場合、実験名を変更する必要はありません。ほとんどの場合、すべてのファイルシステムで名前が一意になるように、コレクタで実験名が作成されるようにしてください。
実験を共通のファイルシステムに格納し、標準形式 experiment. n.er で実験名を指定した場合、実験のたびに n の値が増分されるときに実験名が一意になります。実験は、MPI プロセスによって実験ディレクトリのロックが取得された順序で番号が付けられるので、プロセスの MPI ランクに対応する保証はありません。動作中の MPI ジョブ内の MPI プロセスに dbx を接続した場合、実験の番号は、接続した順序によって決まります。
各実験をそれぞれローカルのファイルシステムに格納し、明示的な実験名を指定すると、実験の名前が同じになる可能性があります。たとえば node0、node1、node2、node3 の 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 コマンドを使用してデータを収集するには、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 で作成されるプロセス数です。この手順では、collect の n 個の個別のインスタンスが作成され、それぞれのインスタンスで実験が記録されます。実験を格納する場所と方法については、「収集データの格納場所」の節をお読みください。
さまざまな MPI ランから集めた実験結果が別々に格納されるようにするために、MPI ランごとに -g オプションで実験グループを作成することができます。実験グループはすべての MPI プロセスからアクセスできるファイルシステムに保存してください。実験グループを作成すると、1 つの MPI ランに関する複数の実験をパフォーマンスアナライザに容易に読み込むこともできます。グループを作成する代わりに、-d オプションで各 MPI ランに個別のディレクトリを指定することもできます。
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 スクリプトです。この手順では、dbx の n 個の個別のインスタンスが作成され、それぞれのインスタンスで 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(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 に格納されます。