パフォーマンス解析の第一段階は、データ収集です。この章では、データ収集のための準備、収集データの格納場所、データの収集方法、およびデータ収集の管理方法について説明します。データそのものの詳細については、第 2 章パフォーマンスデータを参照してください。
カーネルからデータを収集するには、er_kernel という別のツールが必要です。詳細は、第 9 章カーネルプロファイリングを参照してください。
この章では、次の内容について説明します。
プログラムのコンパイル時には、ほとんどのコンパイラオプションを使用してデータの収集および解析を行うことができますが、収集対象とパフォーマンスアナライザでの表示対象に影響するオプションがいくつかあります。プログラムのコンパイルとリンクを行う際に考慮すべき事柄について、このあとの各項で説明します。
注釈付きの「ソース」および「逆アセンブリ」の解析にソースコードを表示し、「行」解析にソース行を表示するには、-g コンパイラオプション (C++ でフロントエンドインライン化を有効にするには -g0) で対象のソースファイルをコンパイルし、デバッグシンボル情報を作成します。デバッグシンボル情報の形式は、-xdebugformat=(dwarf|stabs) によって、DWARF2 またはスタブに指定することができます。デフォルトのデバッグ形式は dwarf です。
データ空間プロファイルを許可するデバッグ情報を含むコンパイルオブジェクトを準備するには、-xhwcprof と任意の最適化レベルを指定してコンパイルします。この方法は現在のところ、SPARC プロセッサだけが対象です。現在は、最適化を行わないと、この機能は使用できません。「データオブジェクト」解析でプログラムデータオブジェクトを表示するには、-g (または C++ の場合は -g0) も追加して十分なシンボル情報を取得します。
DWARF 形式のデバッグ用シンボルで構築された実行可能ファイルやライブラリには、構成要素である各オブジェクトファイルのデバッグシンボルのコピーが自動的に取り込まれます。スタブ形式のデバッグ用シンボルを使用して構築された実行可能ファイルとライブラリの場合、デバッグシンボルのリンク時に -xs オプションが指定され、各種のオブジェクトファイルおよび実行可能ファイル内にスタブシンボルが残されていれば、構成要素である各オブジェクトファイルのデバッグシンボルのコピーが取り込まれます。この情報の取り込みは、オブジェクトファイルを移動したり、削除したりする必要がある場合に特に有用です。すべてのデバッグ用シンボルが実行可能ファイルとライブラリ自体にあるので、実験とプログラム関連ファイルを別の場所に容易に移動できます。
プログラムをコンパイルするときに、-dn および -Bstatic コンパイラオプションを使用して動的リンクを無効にしないでください。完全に静的にリンクされたプログラムのデータを収集しようとしても、コレクタからエラーメッセージが返され、データは収集されません。このエラーが発生する原因は、コレクタを実行したときに、コレクタライブラリが動的に読み込まれるためです。
システムライブラリを静的リンクしないでください。システムライブラリを静的リンクしてしまうと、トレースデータを何も収集できなくなることがあります。また、コレクタライブラリ libcollector.so へもリンクしないでください。
通常、collect コマンドではターゲットのアドレス空間に含まれているすべての共有オブジェクトのデータが、初期ライブラリリストに含まれているものか、dlopen() によって明示的に読み込まれたものかにかかわらず、収集されます。ただし、特定の条件では一部の共有オブジェクトのプロファイリングが行われないことがあります。
遅延読み込みにより指定プログラムが呼び出された場合。この場合、起動時にはライブラリが読み込まれず、dlopen() の呼び出しによって明示的にも読み込まれないため、共有オブジェクトは実験に含まれず、共有されたオブジェクトからの PC はすべて <Unknown> 関数にマップされます。対策として、環境変数 LD_BIND_NOW を設定すると、起動時にライブラリが強制的に読み込まれます。
実行可能ファイルが -B オプションを指定して構築された場合。この場合、そのオブジェクトは、dlopen() の動的リンカーエントリポイントに固有の呼び出しによって読み込まれ、libcollector 割り込みはバイパスされます。共有オブジェクト名は実験には含まれず、共有されたオブジェクトからの PC はすべて <Unknown>() 関数にマップされます。対策は、-B オプションを使用しないことです。
何らかのレベルの最適化を有効にしてプログラムをコンパイルすると、コンパイラにより実行順序が変更され、プログラム内の行の順序と実行順序が厳密に一致しなくなることがあります。この場合、パフォーマンスアナライザは、最適化されたコードについて収集された実験データを解析できますが、しばしば、逆アセンブリレベルでパフォーマンスアナライザが提供するデータを元のソースコード行に対応付けることが困難になります。また、コンパイラが末尾呼び出しの最適化を行う場合には、呼び出しシーケンスが予想とは異なっているように見えることがあります。詳細は、「末尾呼び出しの最適化」を参照してください。
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 10 OS では、コレクタは Solaris C ライブラリ libc.so からの関数に割り込みます。
ヒープトレースデータの収集。コレクタは、malloc、realloc、memalign、free の関数に割り込みます。これらの関数は、C 標準ライブラリ libc.so のほか、libmalloc.so や libmtmalloc.so などのライブラリにあります。
時間データの完全性の確保。コレクタは setitimer に割り込み、プログラムがプロファイルタイマーを使用しないようにします。
ハードウェアカウンタデータの完全性の確保。コレクタは、ハードウェアカウンタライブラリ libcpc.so からの関数に割り込み、プログラムがカウンタを使用しないようにします。プログラムからこのライブラリの関数への呼び出しは、値 -1 を返します。
派生プロセスに対するデータ収集の有効化。コレクタは、fork(2)、fork1(2)、vfork(2)、fork(3F)、posix_spawn(3p)、posix_spawnp(3p)、system(3C)、system(3F)、sh(3F)、popen(3C)、exec(2) の関数とそのバリアントに割り込みます。vfork の呼び出しは、内部で fork1 の呼び出しに置き換えられます。これらの割り込み処理が行われるのは、collect コマンドの場合だけです。
コレクタによる SIGPROF シグナルおよび SIGEMT シグナルの処理の保証。コレクタは sigaction に割り込み、シグナルハンドラがこれらのシグナル用のプライマリシグナルハンドラであるかどうかを確認します。
次のような環境では、割り込みが成功しません。
割り込み対象関数が入っているライブラリとプログラムを静的にリンクした場合。
コレクタライブラリが事前読み込みされていない実行中アプリケーションに dbx を接続した場合。
これらのライブラリのいずれか 1 つを動的に読み込み、このライブラリの中でだけ検索することによってシンボルを解決する場合。
コレクタが割り込み処理を行えなかった場合には、パフォーマンスデータが消去されたり無効になったりする可能性があります。
er_sync.so、er_heap.so、および er_mpviewn.so (n は MPI バージョンを示す) ライブラリは、それぞれ同期待ちトレースデータ、ヒープトレースデータ、または MPI トレースデータが要求された場合のみ読み込まれます。
コレクタは、2 つのシグナルを使用して、プロファイルデータを収集します。SIGPROF はすべての実験に使用され、SIGEMT (Solaris プラットフォームの場合) または SIGIO (Linux プラットフォームの場合) はハードウェアカウンタ実験にのみ使用されます。コレクタは、これらの各シグナルについてシグナルハンドラをインストールします。シグナルハンドラは自身のシグナルをインターセプトして処理しますが、ほかのシグナルは、インストールされているほかのシグナルハンドラに引き渡します。プログラムがこれらのシグナル用に独自のシグナルハンドラをインストールすると、コレクタは自分のシグナルハンドラをプライマリハンドラとして再インストールし、それによって完全なパフォーマンスデータが確保されます。
collect コマンドでは、ユーザー指定のシグナルを使用してデータ収集の一時停止と再開、および標本の記録を行えます。それらのシグナルはコレクタによって保護されませんが、ユーザーハンドラがインストールされている場合は、実験に警告が書き出されます。コレクタとアプリケーションによる指定シグナルの使用が互いに競合しないように、ユーザーが責任を持って確認する必要があります。
コレクタによってインストールされたシグナルハンドラは、システムコールがシグナル配信のために中断されないようにするためのフラグを設定します。このフラグ設定方法では、プログラムのシグナルハンドラがシステムコールの中断を許可するようにフラグを設定した場合に、プログラムの動作が変化する可能性があります。動作が変化する重要な例として、非同期キャンセル処理に SIGPROF を使用し、システムコールの中断を行う非同期入出力ライブラリ libaio.so が挙げられます。コレクタライブラリ libcollector.so がインストールされている場合、キャンセルシグナルの到着は常に、非同期入出力操作を取り消すには遅すぎます。
コレクタライブラリを事前読み込みしないままプロセスに dbx を接続してパフォーマンスデータ収集を有効にし、そのあとでプログラムが自分のシグナルハンドラをインストールすると、コレクタは自分のシグナルハンドラを再インストールしません。この場合、プログラムのシグナルハンドラは、パフォーマンスデータが失われないように、SIGPROF および SIGEMT シグナルが確実に渡されるようにする必要があります。プログラムのシグナルハンドラがシステムコールを中断した場合、プログラムの動作とプロファイルの動作は、コレクタライブラリが事前読み込みされた場合の動作と異なります。
動的ローダーによって課される制約により、setuid(2) を使用してパフォーマンスデータを収集することが困難になります。プログラムが setuid を呼び出すか、setuid ファイルを実行する場合、コレクタは新しいユーザー ID に必要なアクセス権がないために、実験ファイルに書き込めない可能性が高くなります。
collect コマンドは、ターゲットのアドレス空間 (LD_PRELOAD) に共有ライブラリ libcollector.so を挿入して動作します。実行可能ファイルが setuid または setgid を呼び出す、または setuid または setgid を呼び出す子孫プロセスを作成する場合、その実行可能ファイルから collect コマンドを起動すると、いくつかの問題が発生する可能性があります。root ではないユーザーとして実験を実行すると、共有ライブラリが信頼できるディレクトリにインストールされていないために収集が失敗します。対策としては、root ユーザーとして実験を実行するか、crle(1) を使用してアクセス権を与えます。セキュリティバリアーを迂回するときには十分な注意を払い、各自のリスクで行ってください。
collect コマンドを実行するとき、umask は、自分、exec() によって実行されるプログラムの setuid 属性および setgid 属性によって設定されているユーザーまたはグループ、およびプログラム自体によって設定されるユーザーまたはグループに対して、書き込みアクセスを許可するように設定されている必要があります。マスクが正しく設定されていない場合、一部のファイルが実験に対して書き込まれず、実験が処理不能になることがあります。ログファイルが書き込み可能な場合、実験の処理を試みたときにエラーが示されます。
ターゲット自身が UID または GID を設定する何らかのシステムコールを発行した場合、自分の umask を変更してから fork を行うか、ほかの実行可能ファイルを exec() で実行した場合、または crle を使用してランタイムリンカーが共有オブジェクトを検索する方法が構成された場合には、ほかの問題が発生する可能性があります。
実効 GID を変更するターゲット上で実験が root として開始された場合、実験の終了時に実行される er_archive プロセスが失敗します。これは、このプロセスには「信頼できる」にマークされていない共有ライブラリが必要なためです。この場合、実験の終了直後に、実験が記録されたマシン上で、er_archive ユーティリティー (または er_print ユーティリティーか analyzer コマンド) を手作業で明示的に実行できます。
プログラムからデータ収集を制御するために、コレクタ共有ライブラリ libcollector.so に含まれているいくつかの API 関数を使用できます。これらの関数は C で記述されており、Fortran インタフェースも用意されています。ライブラリとともに提供されるヘッダーファイルに、C インタフェースと Fortran インタフェースの両方が定義されています。
API 関数は、次のように定義されます。
void collector_sample(char *name); void collector_pause(void); void collector_resume(void); void collector_terminate_expt(void); |
CollectorAPI クラスに、Java プログラム用の類似の機能が用意されており、これについては、「Java インタフェース」で説明しています。
collectorAPI.h を取り込み、配下の libcollector.so API 関数の存在をチェックする実際の関数を含む、-lcollectorAPI にリンクすることにより、コレクタ API の C/C++ インタフェースにアクセスできます。
有効な実験がない場合、API 呼び出しは無視されます。
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 は Oracle Solaris Studio ソフトウェアがインストールされているディレクトリです) をクラスパスが指している状態で呼び出される必要があります。
import com.sun.forte.st.collector.CollectorAPI; |
Java CollectorAPI メソッドは、次のように定義されます。
CollectorAPI.sample(String name) CollectorAPI.pause() CollectorAPI.resume() CollectorAPI.terminate() |
Java API には、動的関数 API 以外の C および C++ API と同じ関数が含まれています。
C インクルードファイルの libcollector.h には、データが収集されていないときには実際の API 関数への呼び出しを迂回するマクロが含まれています。この場合、関数は動的に読み込まれません。ただし、一部の条件では適切に機能しないことがあるため、これらのマクロを使用するのは危険です。collectorAPI.h はマクロを使用していないため、このファイルを使用する方が安全です。このファイルでは、関数が直接参照されます。
Fortran API サブルーチンはパフォーマンスデータが収集されているときには C API 関数を呼び出し、そうでないときには復帰します。チェック処理のオーバーヘッドは非常に小さいので、プログラムのパフォーマンスにはあまり影響がないはずです。
パフォーマンスデータを収集するには、この章で後述するように、コレクタを使用してプログラムを実行する必要があります。API 関数への呼び出しを挿入することによって、データ収集が有効になることはありません。
マルチスレッドプログラムで API 関数を使用する場合は、これらの関数が 1 つのスレッドによってのみ呼び出されるようにする必要があります。API 関数は、個別のスレッドではなくプロセスに適用される動作を実行します。各スレッドが API 関数を呼び出すと、記録されたデータが期待したものにならない可能性があります。たとえば、あるスレッドが collector_pause() や collector_terminate_expt() を呼び出したときに、ほかのスレッドがまだプログラム内のそのポイントに達していない場合、すべてのスレッドについて収集が一時停止または停止され、この API 呼び出しの前にコードを実行していたスレッドのデータが失われる可能性があります。
ここでは、データ収集に関係する 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++、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 HotSpot 仮想マシンによってコンパイルされる Java メソッドには別のインタフェースが使用されるので、これらの API 関数を使用する必要はありません。Java インタフェースは、コンパイルされたメソッドの名前をコレクタに知らせます。Java コンパイル済みメソッドの関数データと注釈付き逆アセンブリのリストを見ることはできますが、注釈付きソースリストを見ることはできません。
実験への記録のため、動的にコンパイルされた関数に関する情報をコレクタに渡します。パラメータリストを次の表に示します。
表 3–1 collector_func_load() のパラメータリスト
パラメータ |
定義 |
---|---|
name |
パフォーマンスツールで使用する、動的にコンパイルされた関数の名前。実際の関数名でなくてもかまいません。この名前は関数の通常の命名規則に従っている必要はありませんが、空白文字や引用符は含めないようにします。 |
alias |
関数の説明に使用する任意の文字列。NULL も使用できます。この文字列が解釈の対象となることはありません。空白文字を含めることができます。アナライザの「概要」タブに表示されます。何の関数であるか、またはなぜ関数が動的に構築されたかを示すために使用できます。 |
sourcename |
関数の構築元であるソースファイルのパス。NULL も使用できます。このソースファイルは、注釈付きソースリストに使用されます。 |
vaddr |
関数が読み込まれたアドレス。 |
size |
バイト数による関数のサイズ。 |
lntsize |
行番号テーブルのエントリの数を示すカウント。行番号情報がない場合には、ゼロとなります。 |
lntable |
lntsize エントリが入っているテーブル。各エントリは、整数対です。第 1 整数はオフセット、第 2 整数は行番号です。あるエントリのオフセットと次のエントリのオフセットとの間の命令はすべて、最初のエントリの行番号に対応します。オフセットは数値の昇順にする必要がありますが、行番号の順序は任意です。lntable が NULL の場合、関数のソースリストは利用できませんが、逆アセンブリリストは利用できます。 |
アドレス vaddr にある動的関数が読み込み解除されたことをコレクタに通知します。
ここでは、ハードウェア、オペレーティングシステム、プログラムの実行方法、またはコレクタ自体によって課される、データ収集の制限事項について説明します。
異なる種類のデータを同時に収集することについて制限はありません。カウントデータを除いて、任意の種類のデータを同時に収集できます。
コレクタは、最大 16K ユーザースレッドをサポートできます。この数を超えるスレッドからのデータは破棄され、コレクタエラーが生成されます。サポートされるスレッド数を増やすには、SP_COLLECTOR_NUMTHREADS 環境変数に設定されている値を増やします。
デフォルトで、コレクタは、最大 256 フレームの深さまでスタックを収集します。これよりも深いスタックをサポートするには、SP_COLLECTOR_STACKBUFSZ 環境変数に設定されている値を増やします。
プロファイル間隔の最小値と、プロファイルに使用する時間の分解能は、オペレーティング環境により異なります。最大値は 1 秒に設定されています。プロファイル間隔の値は、時間の分解能のもっとも近い倍数に切り捨てられます。最小値および最大値と時間の分解能を検索するには、引数を付けずに collect コマンドを入力します。
時間ベースのプロファイルでは、SIGPROF シグナルがターゲットに送られたときにデータが記録されます。それによってシグナルを処理するための実行時間の拡大が発生し、呼び出しスタックが展開されます。呼び出しスタックが深く、シグナルが頻繁なほど、実行時間の拡大は大きくなります。一定の範囲までは、時間ベースのプロファイルにより、ある程度の実行時間の拡大が生じますが、これはもっとも深いスタックで実行するプログラムの各部分の実行時間の拡大が大きくなることから生まれます。
可能な場合、デフォルト値は正確なミリ秒数でなく、システムクロックとの相関を回避するために、正確な数値と多少異なる値 (たとえば、10.007 ms または 0.997 ms など) に設定されます。システムクロックとの相関はデータのひずみをもたらす場合もあります。SPARC プラットフォームでは、同じ方法でカスタム値を設定してください (Linux プラットフォーム上では不可能)。
コレクタライブラリ libcollector.so が事前読み込みされていないかぎり、すでに稼働中のプログラムからはトレースデータを収集できません。詳細は、「動作中のプロセスからのトレースデータの収集」を参照してください。
データのトレースは、トレースされるイベント数に比例して実行時間を拡大させます。時間ベースのプロファイルを同時に行うと、イベントのトレースに起因する実行時間の拡大により、時間データにひずみが生じます。
ハードウェアカウンタオーバーフローのプロファイルには、次のような制限があります。
ハードウェアカウンタオーバーフローデータの収集を行えるのは、ハードウェアカウンタが用意されていてオーバーフロープロファイルをサポートしているプロセッサにおいてだけです。そのほかのシステムでは、ハードウェアカウンタオーバーフローのプロファイルは無効です。UltraSPARC III プロセッサファミリより前の UltraSPARC プロセッサは、ハードウェアカウンタオーバーフローのプロファイルをサポートしません。
Solaris OS を実行しているシステムで、cpustat(1) コマンドを実行中にハードウェアカウンタオーバーフローのデータを収集することはできません。これは、cpustat がカウンタを制御しており、ユーザープロセスがカウンタを利用できないためです。データ収集中に cpustat を起動すると、ハードウェアカウンタオーバーフローのプロファイルは終了され、実験にエラーが記録されます。
ハードウェアカウンタオーバーフローのプロファイルを行う場合、独自のコードでハードウェアカウンタを使用することはできません。コレクタは libcpc ライブラリ関数に割り込み、コレクタからの呼び出しではなかった場合、-1 の戻り値で復帰します。ハードウェアカウンタへのアクセスの取得に失敗した場合に正常に機能するようにプログラムをコーディングする必要があります。この処理を行うようにコーディングされていない場合、ハードウェアカウンタプロファイル時に、スーパーユーザーがカウンタを使用するシステム全体のツールを起動した場合、またはそのシステムでカウンタがサポートされていない場合にプログラムが失敗します。
dbx をプロセスに接続することによって、ハードウェアカウンタライブラリを使用している実行中プログラムのハードウェアカウンタデータを収集しようとすると、実験が壊れることがあります。
使用可能なすべてのカウンタの一覧を表示するには、引数を指定せずに collect コマンドを実行します。
ハードウェアカウンタオーバーフローのプロファイルは、SIGEMT シグナル (Solaris プラットフォームの場合) または SIGIO シグナル (Linux プラットフォームの場合) がターゲットへ配信された時点のデータを記録します。それによってシグナルを処理するための実行時間の拡大が発生し、呼び出しスタックが展開されます。時間ベースのプロファイルと違い、ハードウェアカウンタによっては、プログラムのさまざまな部分がその他の部分より高速にイベントを生成する場合があり、そのコード部分に実行時間の拡大が生じます。そのようなイベントを非常に高速に生成するプログラムの一部で大きなひずみが生じる場合があります。同様に、あるスレッドでは、ほかのスレッドと不均等にイベントが生成されるものがあります。
派生プロセスのデータ収集には、いくつかの制限事項があります。
コレクタでの派生プロセスすべてについてデータを収集するには、次のいずれかのオプションとともに collect コマンドを使用する必要があります。
-F on オプションを使用すると、fork とそのバリアント、および exec とそのバリアントへの呼び出しについて、自動的にデータを収集できます。
-F all オプションを使用すると、コレクタは、system、popen、posix_spawn(3p)、posix_spawnp(3p)、および sh の呼び出しに起因するものを含むすべての派生プロセスを追跡します。
-F '=regexp' オプションを使用すると、名前または系統が指定した正規表現と一致するすべての派生プロセスに関するデータを収集できます。
-F オプションについては、「実験制御オプション」を参照してください。
プログラム実行中に OpenMP データを収集すると非常にコストが高くなる可能性があります。このコストを抑制するには、SP_COLLECTOR_NO_OMP 環境変数を設定します。この設定を行うと、プログラムの遅延は大幅に減少しますが、スレーブトレッドから呼び出し元へ、最終的には main() へ伝搬されるデータは、この変数がない場合には参照可能ですが、この変数を設定すると参照できなくなります。
このリリースでは、デフォルトで OpenMP 3.0 の新しいコレクタが有効になっています。このコレクタは、明示的なタスクを使用するプログラムのプロファイルを実行できます。以前のバージョンのコンパイラで構築されたプログラムは、libmtsk.so のパッチ適用済みバージョンが利用可能な場合にのみ、新しいコレクタでプロファイル可能です。このパッチ適用済みバージョンがインストールされていない場合、SP_COLLECTOR_OLDOMP 環境変数を設定し、データ収集が古いコレクタを使用するように切り替え可能です。
OpenMP プロファイル機能は Oracle Solaris Studio コンパイラ実行時のランタイムに依存しているため、Oracle Solaris Studio コンパイラでコンパイルされたアプリケーションに対してのみ使用できます。GNU コンパイラでコンパイルされたアプリケーションの場合、マシンレベルの呼び出しスタックのみが表示されます。
Java プログラムのデータ収集には、次の制限事項があります。
Java 2 Software Development Kit (JDK) の JDK 6、Update 18 またはそれ以降のバージョンを使用する必要があります。コレクタは、JDK_HOME 環境変数または環境変数のパスセットに含まれている JDK を最初に探します。JAVA_PATHこれらの変数がいずれも設定されていない場合、使用されている環境の PATH に含まれている JDK を探します。PATH にも JDK が存在しない場合、/usr/java/bin/java の java 実行可能ファイルを探します。コレクタは、見つかった java 実行可能ファイルのバージョンが ELF 実行可能ファイルであるかどうかを検証し、そうでない場合は、使用した環境変数またはパスと、試みたフルパス名を示すエラーメッセージを出力します。
ホットスポットコンパイルコードのソース行マッピングの詳細情報を取得するには、JDK 6、Update 20、JDK 7、build b85 Early Access リリース、またはそれ以降のバージョンを使用する必要があります。
データを収集するには、collect コマンドを使用する必要があります。dbx collector サブコマンドは使用できません。
JVM ソフトウェアを実行する派生プロセスを作成するアプリケーションはプロファイルできません。
一部のアプリケーションは純粋な Java ではなく、C または C++ アプリケーションで、dlopen() を起動して libjvm.so を読み込んでから、その中への呼び出しを行って JVM ソフトウェアを開始します。このようなアプリケーションのプロファイルを行うには、SP_COLLECTOR_USE_JAVA_OPTIONS 環境変数を設定し、collect コマンド行に -j on オプションを追加します。この場合は、LD_LIBRARY_PATH 環境変数を設定しないでください。
Java のプロファイリングでは、Java Virtual Machine Tools Interface (JVMTI) が使用され、実行のひずみと実行時間の拡大が発生する場合があります。
時間ベースのプロファイリングとハードウェアカウンタオーバーフローのプロファイルリングの場合、データ収集プロセスは JVM ソフトウェアへのさまざまな呼び出しを行い、プロファイリングイベントをシグナルハンドラ内で処理します。これらのルーチンのオーバーヘッドとディスクへの実験の書き込みコストにより、Java プログラムの実行時間の拡大が生じます。そのような実行時間の拡大は通常 10% より少なくなります。
アプリケーションの 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 引数を使用して、実験グループを作成することもできます。
派生プロセスの実験は、系統によって次のように命名されます。派生プロセスの実験名は、作成元の実験名の根幹部に下線、コード文字、および番号を追加したものになります。コード文字は、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 (「setpath path_list」 を参照) および addpath (「addpath path_list」 を参照) 指示を使用します。pathmap コマンドで検索を拡張することもできます。
プログラムに対応する、正しい注釈付きソースコードと注釈付き逆アセンブリコードが確実に表示されるようにするには、ソースコード、オブジェクトファイル、および実行可能ファイルを実験にコピーしてから、実験の移動やコピーを行います。オブジェクトファイルをコピーしたくない場合は、-xs を使用してプログラムをリンクし、ソース行とファイルの場所に関する情報が実行可能ファイルに挿入されるようにします。collect コマンドの -A copy オプション、または dbx collector archive コマンドを使用すると、ロードオブジェクトを実験に自動的にコピーすることができます。
ここでは、実験を記録するために必要な空きディスク容量を概算するためのいくつかのガイドラインを示します。実験のサイズはデータパケットのサイズとその記録速度、プログラムが使用する LWP の数、およびプログラムの実行時間によって異なります。
データパケットには、イベント固有のデータと、プログラム構造に依存するデータ (呼び出しスタック) が含まれます。データのサイズはデータの種類に依存し、約 50 ~ 100 バイトです。呼び出しスタックのデータは すべての呼び出しの復帰アドレスで構成され、アドレス 1 個あたりのサイズは 4 バイト、64 ビットの実行可能ファイルではアドレス 1 個あたり 8 バイトです。LWP ごとにデータパケットが実験に記録されます。Java プログラムの場合、対象となる呼び出しスタックは Java 呼び出しスタックとマシン呼び出しスタックの 2 つがあるため、ディスクに書き込まれるデータが増えます。
プロファイルデータパケットが記録される頻度は、クロックデータのプロファイル間隔、ハードウェアカウンタデータのオーバーフロー値、および (関数のトレースの場合) トレース対象の関数の出現頻度によって決定されます。プロファイル間隔パラメータの選択は、データの品質や、データ収集オーバーヘッドに起因するプログラムパフォーマンスの偏向にも影響します。これらのパラメータ値が小さければ良い統計値が得られますが、オーバーヘッドは高くなります。プロファイル間隔とオーバーフロー値のデフォルト値は、良好な統計値を得ることとオーバーヘッドを抑えることの折衷点として慎重に選択されています。値が小さい場合、データ量が多いことを意味します。
時間ベースのプロファイル実験、またはハードウェアカウンタオーバーフロープロファイル実験で、プロファイル間隔が毎秒 100 サンプル前後、パケットサイズが小さな呼び出しスタックで 80 バイト、大きな呼び出しスタックで 120 バイトの範囲であれば、記録されるデータはスレッドあたり毎秒 10K バイト程度です。数百という深さを持つ呼び出しスタックを持つプログラムの場合は、この 10 倍以上の速度でデータが記録される可能性があります。
MPI トレース実験では、データ量はトレース対象の MPI 呼び出しごとに 100 - 150 バイトで、送信されるメッセージの数や呼び出しスタックの深さによって異なります。さらに、collect コマンドの -M オプションを使用しているときは、デフォルトで時間プロファイルが有効なため、時間プロファイル実験の推定値を加算します。-p off オプションで時間プロファイルを無効にすると、MPI トレースのデータ量を減らすことができます。
コレクタは、MPI トレースデータを独自の形式 (mpview.dat3) と、VampirTrace OTF 形式 (a.otf、 a.*.z) の両方で格納します。OTF 形式のファイルを削除しても、アナライザに影響はありません。
実験サイズの概算では、アーカイブファイルに使用されるディスク容量も考慮する必要がありますが、通常その量は、必要となるディスク容量全体のごく一部です (前節参照)。必要なディスク容量のサイズを確定できない場合は、実験を短時間だけ行なってみてください。この実験からアーカイブファイルのサイズを取得し (データ収集時間とは無関係)、プロファイルファイルのサイズを確認することによって、完全な実験のサイズを概算できます。
コレクタは、ディスク容量を割り当てるだけでなく、ディスクにプロファイルデータを書き込む前に、そのデータを格納するためのバッファーをメモリー内に確保します。現在、こうしたバッファーのサイズを指定する方法はありません。コレクタがメモリー不足になった場合、収集するデータ量を減らすようにしてください。
現在利用できる容量より実験の格納に必要となる容量の方が大きいと思われる場合には、実行の全体でなく一部だけのデータを収集することを検討してください。実行の一部についてのデータを収集するには、collect コマンドを -y または -t オプションで実行するか、dbx collector サブコマンドを使用するか、またはコレクタ API への呼び出しをプログラムに挿入します。collect コマンドの -L オプションや、dbx collector サブコマンドを使用して、収集されるプロファイルおよびトレースデータの総量を制限することもできます。
パフォーマンスアナライザでパフォーマンスデータを複数の方法で収集できます。
コマンド行から collect コマンドを使用する (「collect コマンドによるデータの収集」 および collect(1) のマニュアルページを参照)。collect コマンド行ツールは dbx よりもデータ収集のオーバーヘッドが小さいため、この方法のほうが適切な場合があります。
Oracle Solaris Studio で、パフォーマンスアナライザの「パフォーマンスコレクタ」ダイアログボックスを使用する (パフォーマンスアナライザのオンラインヘルプの「Oracle Solaris Studio パフォーマンスコレクタダイアログボックスによるパフォーマンスデータの収集」を参照)。
dbx コマンド行から collector コマンドを使用する (「dbx collector サブコマンドによるデータの収集」を参照)。
次のデータ収集機能は、Oracle Solaris Studio の「収集」ダイアログボックスと、collect コマンドでのみ使用できます。
Java プログラムに関するデータの収集。dbx の collector コマンドで Java プログラムに関するデータの収集を試みた場合、実際に収集される情報は、Java プログラムではなく JVM ソフトウェアに関する情報です。
派生プロセスに関するデータの自動収集。
collect コマンドを使用してコマンド行からコレクタを実行するには、次のコマンドを使用します。
% collect collect-options program program-arguments |
ここで、collect-options は collect コマンドのオプションで、program はデータ収集対象のプログラム名、program-arguments はプログラムの引数です。ターゲットプログラムは通常、バイナリ実行可能ファイルです。ただし、環境変数 SP_COLLECTOR_SKIP_CHECKEXEC を設定する場合は、ターゲットとしてスクリプトを指定できます。
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/ からダウンロードできます。インストール方法の指示は、tar ファイルに含まれています。ユーザーレベルの libperfctr.so ライブラリは、LD_LIBRARY_PATH 環境変数の値を使用して検索されたあとで、32 ビットバージョンでは /usr/local/lib、/usr/lib、および /lib で、64 ビットバージョンでは /usr/local/lib64、/usr/lib64、および /lib64 で検索されます。
使用可能なカウンタの一覧を表示するには、引数なしで collect コマンドを端末ウィンドウに入力します。カウンタの一覧については、「ハードウェアカウンタのリスト」を参照してください。ほとんどのシステムでは、カウンタが一覧に記載されていない場合でも、16 進数または 10 進数の数値で指定できます。
カウンタ定義には、プロセッサがハードウェアカウンタの属性をサポートしているかどうかに応じて、次のいずれかの形式を使用できます。
[+]counter_name[/ register_number][,interval ]
[+]counter_name[~ attribute_1=value_1]...[~attribute_n =value_n][/ register_number][,interval ]
プロセッサ固有の counter_name には、次のいずれかを指定できます。
カウンタ名の別名
生の名前
10 進数または 16 進数の数値
複数のカウンタを指定する場合、それらのカウンタは異なるレジスタを使用する必要があります。同じレジスタが指定された場合、collect コマンドはエラーメッセージを出力して終了します。
ハードウェアカウンタがメモリーアクセスに関連するイベントをカウントする場合、カウンタ名の前に + 記号を付けて、カウンタのオーバーフローを発生させた命令の実際のプログラムカウンタアドレス (PC) の検索をオンにすることができます。バックトラッキングは SPARC プロセッサ上で、load、store、load-store のいずれかのタイプのカウンタでのみ機能します。検索が成功すると、仮想 PC、物理 PC、および参照された有効アドレスがイベントデータパケットに格納されます。
一部のプロセッサでは、属性オプションをハードウェアカウンタと関連付けることができます。プロセッサが属性オプションをサポートしている場合は、collect コマンドを引数リストなしで実行すると、属性名を含むカウンタ定義が一覧表示されます。属性値は、10 進数または 16 進数形式で指定できます。
間隔 (オーバーフロー値) は、ハードウェアカウンタがオーバーフローしてオーバーフローイベントが記録されたときにカウントされたイベントまたはサイクルの数です。間隔は、次のいずれかに設定できます。
on または NULL 文字列 - デフォルトのオーバーフロー値で、collect を引数なしで入力することによって判別できます。
hi[gh] - 選択したカウンタの高分解能値で、デフォルトのオーバーフロー値の約 1/10 です。旧バージョンのソフトウェアとの互換を図るため、h の省略形もサポートされています。
lo[w] - 選択したカウンタの低分解能値で、デフォルトのオーバーフロー値の約 10 倍です。
interval - 特定のオーバーフロー値で、10 進数または 16 進数形式の正の整数です。
デフォルトでは、各カウンタに定義済みの通常のしきい値が使用されます。これらの値はカウンタの一覧に表示されます。「ハードウェアカウンタオーバーフローのプロファイルに関する制限事項」も参照してください。
-p オプションを明示的に指定せずに -h オプションを使用すると、時間ベースのプロファイルが無効となります。ハードウェアカウンタデータと時間ベースデータの両方を収集するには、-h オプションと -p オプションの両方を指定する必要があります。
同期待ちトレースデータを収集します。option に使用できる値は次のとおりです。
all - しきい値 0 で同期待ちトレースを有効にします。このオプションは、すべての同期イベントの記録を強制的に有効にします。
calibrate - 同期待ちトレースを有効にし、実行時に測定を行うことによってしきい値を設定します。on と等価です。
off - 同期待ちトレースを無効にします。
on - 同期待ちトレースを有効にし、デフォルトのしきい値 (実行時の測定により値を決定) に設定します。calibrate と等価です。
Java プログラムでは同期待ちトレースデータは記録されず、指定するとエラーとして処理されます。
Solaris では、次の関数がトレースされます。
mutex_lock() |
rw_rdlock() |
rw_wrlock() |
cond_wait() |
cond_timedwait() |
cond_reltimedwait() |
thr_join() |
sema_wait() |
pthread_mutex_lock() |
pthread_rwlock_rdlock() |
pthread_rwlock_wrlock() |
pthread_cond_wait() |
pthread_cond_timedwait() |
pthread_cond_reltimedwait_np() |
pthread_join() |
sem_wait() |
Linux では、次の関数がトレースされます。
pthread_mutex_lock() |
pthread_cond_wait() |
pthread_cond_timedwait() |
pthread_join() |
sem_wait() |
ヒープトレースデータを収集します。option に使用できる値は次のとおりです。
on - ヒープの割り当て要求および割り当て解除要求のトレースを有効にします。
off - ヒープトレースを無効にします。
デフォルトでは、ヒープのトレースは無効です。ヒープトレースは Java プログラムについてはサポートされず、指定するとエラーとして処理されます。
MPI 実験の収集を指定します。collect コマンドのタ−ゲットは mpirun コマンドである必要があります。また、mpirun コマンドのオプションは、‐‐ オプションを使って mpirun コマンドによって実行されるターゲットプログラムと分けて指定されることが必要です。(mpirun コマンドでは常に ‐‐ オプションを使用することで、collect コマンドとそのオプションを mpirun コマンド行の先頭に追加し、実験を収集できます。)この実験には通常の名前が付けられ、親の実験と呼ばれます。ディレクトリには MPI プロセスのそれぞれについて、ランクにより命名されたサブ実験が含まれます。
option に使用できる値は次のとおりです。
MPI-version - MPI 実験の収集を有効にします。指定された MPI バージョンが使用されます。MPI バージョンは、OMPT、CT、OPENMPI、MPICH2、MVAPICH2 のいずれかであることが必要です。Oracle Message Passing Toolkit は OMPT または CT を使用して指定できます。
off - MPI 実験の収集を無効にします。
デフォルトでは、MPI 実験の収集は無効になっています。MPI 実験の収集が有効な場合、-m オプションのデフォルト設定は on に変更されます。
collect コマンドをオプションなしで入力するか、-M オプションで認識されないバージョンを指定すると、MPI のサポートされているバージョンが表示されます。
MPI トレースデータを収集します。option に使用できる値は次のとおりです。
on - MPI トレース情報を有効にします。
off - MPI トレース情報を無効にします。
MPI トレースは、デフォルトで無効です。ただし -M オプションが有効な場合は、デフォルトで有効になります。通常、MPI 実験は -M オプションで収集され、MPI トレースのユーザー制御は不要です。MPI 実験の収集を行うが、MPI トレースデータは収集しない場合、明示的なオプションの -M MPI-version -m off を使用します。
呼び出しがトレースされる MPI 関数とトレースデータをもとに計算されるメトリックスの詳細については、「MPI トレースデータ」を参照してください。
標本パケットを定期的に記録します。option に使用できる値は次のとおりです。
off - 定期的標本収集を無効にします。
on - 定期的標本収集を有効にし、デフォルトの標本収集間隔 (1 秒) を設定します。
デフォルトでは、1 秒間隔による定期的標本収集が有効になります。
カウントデータを記録します (Solaris システムのみ)。
この機能を使用するには、Add-on Cool Tools for OpenSPARC に含まれているバイナリインタフェースツール (Binary Interface Tool、BIT) をインストールする必要があります。このツールは、http://cooltools.sunsource.net/ からダウンロードできます。BIT は、Solaris バイナリのパフォーマンスやテストスイートカバレージの測定用ツールです。
option には次のいずれかの値を指定できます。
on - 関数と命令のカウントデータの収集を有効にします。カウントデータと、シミュレートされたカウントデータは、実行可能ファイル、および設置されており実行可能ファイルが静的にリンクされている任意の共有オブジェクトについて、それらの実行可能ファイルと共有オブジェクトが -xbinopt=prepare オプションでコンパイルされたものであれば、記録されます。静的にリンクされていても -xbinopt=prepare オプションでコンパイルされていないそのほかの共有オブジェクトは、データに含まれません。動的に開かれる共有オブジェクトは、シミュレートされたカウントデータに含まれません。
関数、行などのカウントメトリックスに加えて、パフォーマンスアナライザの「命令頻度」タブ、または er_print ifreq コマンドにより、さまざまな命令の利用率の概要を確認することもできます。
off - カウントデータの収集を無効にします。
static - ターゲットの実行可能ファイル、および静的にリンクされている共有オブジェクト内で、すべての命令が 1 回だけ実行されたという前提で実験を生成します。-c on オプションと同様に、-c static オプションも、実行可能ファイルと共有オブジェクトが -xbinopt=prepare フラグを指定してコンパイルされている必要があります。
デフォルトでは、カウントデータの収集を無効にします。ほかの種類のデータについて、カウントデータを収集することはできません。
bit 計測のディレクトリを指定します。このオプションは Solaris システムでのみ使用可能で、-c オプションも同時に指定されている場合のみ意味を持ちます。
bit() 計測から除外するライブラリを指定します。ここで指定したものは、ライブラリが実行可能ファイルにリンクされているか、dlopen() によって読み込まれるかにかかわらず、除外されます。このオプションは Solaris システムでのみ使用可能で、-c オプションも同時に指定されている場合のみ意味を持ちます。-N オプションは複数指定できます。
スレッドアナライザ用に、データ競合検出またはデッドロック検出のデータを収集します。次のいずれかの値を指定できます。
race - データ競合検出のデータを収集します。
deadlock - デッドロックと潜在的デッドロックのデータを収集します。
all - データ競合検出とデッドロック検出のデータを収集します。
off - スレッドアナライザのデータを無効にします。
collect -r コマンドとスレッドアナライザについての詳細は、『Oracle Solaris Studio 12.2: スレッドアナライザユーザーズガイド』および tha (1) のマニュアルページを参照してください。
これらのオプションは、実験データの収集方法を制御します。
派生プロセスのデータを記録するかどうかを制御します。option に使用できる値は次のとおりです。
on - 関数 fork、exec、およびそのバリアントによって作成される派生プロセスについてのみ実験を記録します。
all - すべての派生プロセスについて実験を記録します。
off - 派生プロセスの実験を記録しません。
= regexp - 指定された正規表現と名前または系統が一致する、派生プロセスの実験をすべて記録します。
デフォルトでは、-F on オプションが設定されるので、コレクタは、fork(2)、fork1(2)、fork(3F)、vfork(2)、および exec(2) 関数とそのバリアントの呼び出しによって作成されたプロセスを追跡します。vfork への呼び出しは、内部で fork1 への呼び出しに置換されます。
MPI 実験では、デフォルトで派生も追跡されます。
-F all オプションを指定すると、コレクタは、system(3C)、system(3F)、sh(3F)、posix_spawn(3p)、posix_spawnp(3p)、および 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 は Java 仮想マシンで、JDK 6、Update 18 またはそれ以降の必要があります。collect コマンドは、program が JVM で、かつ ELF 実行可能ファイルであることを検証し、そうでない場合は collect コマンドがエラーメッセージを出力します。
64 ビット JVM を使用してデータを収集する場合、32 ビット JVM 用の java コマンドに -d64 オプションを使用しないでください。これを使用すると、データは収集されません。その代わりに、collect コマンドの program 引数、あるいは JDK_HOME または JAVA_PATH 環境変数に、64 ビット JVM へのパスを指定する必要があります。
プロファイルで使用するために JVM へ渡される追加引数を指定します。-J オプションを指定し、Java プロファイルを指定しない場合、エラーが生成され、実験は実行されません。java_argument に複数の引数が含まれる場合、全体を引用符でくくる必要があります。この引数は、空白またはタブで区切られた一連のトークンで構成される必要があります。各トークンは、別々の引数として JVM へ渡されます。JVM へのほとんどの引数は、「-」文字で始まる必要があります。
signal という名前のシグナルがプロセスへ送信されたときに、標本パケットを記録します。
シグナルは、完全なシグナル名、先頭文字 SIG を省いたシグナル名、またはシグナル番号のいずれの形式でも指定できます。ただし、プログラムが使用するシグナル、または実行を終了するシグナルは指定しないでください。推奨するシグナルは SIGUSR1 および SIGUSR2 です。 SIGPROF は、時間プロファイリングが指定されている場合でも使用できます。シグナルは、kill コマンドを使用してプロセスに送信できます。
-l および -y の両方のオプションを使用する場合は、それぞれのオプションに異なるシグナルを使用する必要があります。
プログラムに独自のシグナルハンドラがあるときにこのオプションを使用する場合は、-l で指定するシグナルが、阻止されたり無視されたりすることなく、確実にコレクタのシグナルハンドラに渡されるようにする必要があります。
シグナルについては、signal(3HEAD) のマニュアルページを参照してください。
データ収集の時間範囲を指定します。
duration は単独の数値として指定でき、オプションとして m または s 接尾辞を付け、実験終了までの時間が分単位か秒単位かを示すこともできます。 デフォルトでは、所要時間は秒です。所要時間はハイフンで区切られた 2 つの数で指定することもできます。これは、1 つ目の時間が経過するまでデータ収集を停止し、そして、データ収集を始める時間を示しています。2 つ目の時間が経過すると、データ収集が終了されます。2 つ目の時間がゼロの場合、初めてプログラムが停止したあと、そのプログラムの実行の終わりまで、データの収集が実行されます。実験が終了しても、ターゲットプロセスは最後まで実行できます。
デバッガがプロセスに接続できるよう、exec システムコールの終了時にターゲットプロセスを停止したままにします。dbx をプロセスに接続した場合は、dbx コマンドの ignore PROF と ignore EMT を使用して、収集シグナルが確実に collect コマンドに渡されるようにします。
signal という名前のシグナルで、データの記録を制御します。このシグナルがプロセスに送信されると、一時停止状態 (データは記録されない) と記録状態 (データは記録される) が切り替わります。ただし、このスイッチの状態に関係なく、標本ポイントは常に記録されます。
シグナルは、完全なシグナル名、先頭文字 SIG を省いたシグナル名、またはシグナル番号のいずれの形式でも指定できます。ただし、プログラムが使用するシグナル、または実行を終了するシグナルは指定しないでください。推奨するシグナルは SIGUSR1 および SIGUSR2 です。 SIGPROF は、時間プロファイリングが指定されている場合でも使用できます。シグナルは、kill コマンドを使用してプロセスに送信できます。
-l および -y の両方のオプションを使用する場合は、それぞれのオプションに異なるシグナルを使用する必要があります。
-y オプションに r 引数 (省略可能) を指定した場合、コレクタは記録状態で起動します。-y オプションが使用されていない場合、コレクタは記録状態で起動します。
プログラムに独自のシグナルハンドラがあるときにこのオプションを使用する場合は、-y で指定するシグナルが、阻止されたり、無視されたりすることなく、確実にコレクタのシグナルハンドラに渡されるようにする必要があります。
シグナルについては、signal(3HEAD) のマニュアルページを参照してください。
これらのオプションは、コレクタによって生成される実験を制御します。
記録する実験の名前として experiment_name を使用します。experiment_name 文字列は文字列「.er」で終わる必要があり、そうでない場合、collect ユーティリティーはエラーメッセージを出力して終了します。
-o オプションを指定しない場合、実験名を「stem.n.er」(stem は文字列、n は数値) の形式で指定します。-g オプションでグループ名を指定した場合、stem を「.erg」接尾辞なしのグループ名に設定します。グループ名を指定していない場合、stem を文字列「test」に設定します。
collect コマンドを、MPI ジョブの実行に使用されるコマンドの 1 つ、たとえば mpirun から起動し、-M MPI-version オプションおよび -o オプションを指定しない場合、そのプロセスの MPI ランクを定義するために使用された環境変数から、名前に使用されている n の値を使用します。それ以外の場合、現在使用されている最も大きい整数値に 1 を加えた値を n に設定します。
名前が「stem.n.er」の形式で指定されておらず、与えられた名前がすでに使用されている場合、エラーメッセージが表示され、実験は実行されません。名前が「stem.n .er」の形式で、与えられた名前がすでに使用されている場合、現在使用されている最も大きい数値より 1 大きい n の値に対応する名前で、実験が記録されます。名前が変更された場合、警告が表示されます。
directory-name というディレクトリに実験を格納します。このオプションは個別の実験にのみ適用され、実験グループには適用されません。ディレクトリが存在しない場合、collect ユーティリティーはエラーメッセージを出力して終了します。-g オプションでグループが指定されている場合、グループファイルも directory-name へ書き込まれます。
データ収集をできるだけ軽くするには、レコードデータをローカルファイルに記録し、-d オプションを使用してデータ格納ディレクトリを指定するのが最適です。ただし、クラスタ上の MPI 実験では、すべてのプロセスから、記録されたすべてのデータが親の実験に書き込まれるため、親の実験がどのプロセスからでも同じパスに存在する必要があります。
待ち時間の長いファイルシステムに書き込まれる実験は特に問題が発生しやすく、標本データが収集される場合 (デフォルトの -S on オプション) には特に、非常に低速になることがあります。待ち時間の長い接続を経由して記録を行う必要がある場合には、標本データを無効にしてください。
実験を group-name という実験グループに含めます。group-name の末尾が .erg でない場合、collect ユーティリティーはエラーメッセージを出力して終了します。グループが存在する場合は、そのグループに実験が追加されます。group-name が絶対パスでない場合、-d でディレクトリを指定されていれば、実験グループがディレクトリ directory-name に、それ以外の場合は現在のディレクトリに格納されます。
ターゲットプロセスで使用されるロードオブジェクトを、記録済み実験に保管またはコピーするかどうかを管理します。option に使用できる値は次のとおりです。
off – ロードオブジェクトを実験に保管しません。
on – ロードオブジェクトを実験に保管します。
copy – ロードオブジェクト (ターゲット、およびターゲットが使用するすべての共有オブジェクト) を実験にコピーして保管します。
実験データが記録されたマシンとは異なるマシンに実験データをコピーするか、異なるマシンから実験データを読み取る場合は、 - A copy を指定します。このオプションを使用しても、ソースファイルまたはオブジェクトファイル (.o) は実験にコピーされません。これらのファイルが、実験の検査に使用するマシンからアクセス可能で、変更されていないことを確認してください。
記録するプロファイルデータの量を sizeM バイトに制限します。この制限は、時間ベースのプロファイルデータ、ハードウェアカウンタオーバーフローのプロファイルデータ、および同期待ちのトレースデータの合計に適用されますが、標本ポイントには適用されません。この制限値は概数にすぎないので、この値を超えることは可能です。
制限に達すると、それ以上のプロファイルデータは記録されませんが、ターゲットプロセスが終了するまで実験はオープン状態となります。定期的な標本収集が有効である場合、標本ポイントの書き込みが継続されます。
約 2G バイトの制限を付けるには、たとえば、-L 2000 を指定します。指定するサイズは、ゼロより大きい必要があります。
デフォルトでは、記録されるデータサイズに制限はありません。
collect 自体の全出力を指定された file に付加しますが、生成されたターゲットからの出力はリダイレクトしません。ファイルが /dev/null に設定されている場合は、エラーメッセージを含む collect の全出力が抑制されます。
これらの collect コマンドオプションはさまざまな目的で使用されます。
dbx が指定された process_id のプロセスに接続し、データを収集してから、スクリプト上で dbx を起動するためのスクリプトを作成します。プロファイルデータのみを指定でき、トレースデータは指定できません。時間指定の実行 (-t オプション) はサポートされません。
実験の 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 にプログラムを読み込みます。
% dbx program |
collector コマンドを使用してデータの収集を有効にし、データの種類を選択し、オプションのパラメータを適宜設定します。
(dbx) collector subcommand |
利用可能な collector サブコマンドの一覧を表示するには、次のコマンドを使用します。
(dbx) help collector |
サブコマンドごとに collector コマンドを 1 つ使用する必要があります。
使用する dbx のオプションを設定し、プログラムを実行します。
指定したサブコマンドに誤りがある場合は、警告メッセージが出力され、サブコマンドは無視されます。このあとに、collector の全サブコマンドをまとめます。
次のサブコマンドを、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 [~ attribute_1=value_1]...[~ attribute_n =value_n][/ register_number][,interval ]
ハードウェアカウンタの name を選択し、そのオーバーフロー値を interval に設定します。オプションとして、追加のハードウェアカウンタ名を選択し、それらのオーバーフロー値を指定された間隔に設定します。オーバーフロー値は次のいずれかです。
on または NULL 文字列 - デフォルトのオーバーフロー値で、collect を引数なしで入力することによって判別できます。
hi[gh] - 選択したカウンタの高分解能値で、デフォルトのオーバーフロー値の約 1/10 です。旧バージョンのソフトウェアとの互換を図るため、h の省略形もサポートされています。
lo[w] - 選択したカウンタの低分解能値で、デフォルトのオーバーフロー値の約 10 倍です。
interval - 特定のオーバーフロー値で、10 進数または 16 進数形式の正の整数です。
複数のカウンタを指定する場合、それらのカウンタは異なるレジスタを使用する必要があります。使用するレジスタが同じである場合は警告メッセージが出力され、コマンドは無視されます。
ハードウェアカウンタがメモリーアクセスに関連するイベントをカウントする場合、カウンタ名の前に + 記号を付けて、カウンタのオーバーフローを発生させた命令の実際の PC の検索をオンにすることができます。検索が成功すると、PC と参照された有効アドレスがイベントデータパケットに格納されます。
デフォルトでは、コレクタは、ハードウェアカウンタのオーバーフロープロファイルデータを収集しません。ハードウェアカウンタオーバーフローのプロファイルが有効になっていて profile コマンドが指定されていない場合、時間ベースのプロファイルは無効となります。
「ハードウェアカウンタオーバーフローのプロファイルに関する制限事項」も参照してください。
同期待ちトレースデータの収集を制御します。option に使用できる値は次のとおりです。
on - デフォルトのしきい値で同期待ちトレースを有効にします。
off - 同期待ちトレースを無効にします。
threshold value - 同期遅延の最小しきい値を設定します。value に使用できる値は次のとおりです。
ヒープトレースデータの収集を制御します。option に使用できる値は次のとおりです。
on - ヒープトレースを有効にします。
off - ヒープトレースを無効にします。
デフォルトでは、コレクタはヒープのトレースデータを収集しません。
スレッドアナライザ用に、データ競合検出またはデッドロック検出のデータを収集します。次のいずれかの値を指定できます。
off – スレッドアナライザのデータ収集を無効にします。
all – すべてのスレッドアナライザデータを収集します。
race - データ競合検出データを収集します。
deadlock - デッドロックと潜在的デッドロックのデータを収集します。
スレッドアナライザについての詳細は、『Oracle Solaris Studio 12.2: スレッドアナライザユーザーズガイド』および tha.1 のマニュアルページを参照してください。
標本収集モードを制御します。option に使用できる値は次のとおりです。
periodic - 定期的な標本収集を有効にします。
manual - 定期的な標本収集を無効にします。手動の標本収集は有効のままです。
デフォルトでは、標本収集間隔 value が 1 秒での定期的な標本収集が有効となります。
dbx がターゲットプロセスを停止したときに、標本を記録するかどうかを制御します。キーワードの意味は、次のとおりです。
on - dbx がターゲットプロセスを停止するたびに標本が記録されます。
off - dbx がターゲットプロセスを停止したときに標本は記録されません。
デフォルトでは、dbx がターゲットプロセスを停止したとき、標本が記録されます。
次のサブコマンドを、dbx 内で collector コマンドとともに使用して、コレクタによる実験データの収集を制御できます。実験がアクティブな場合は、警告メッセージが出力され、サブコマンドは無視されます。
データ収集を無効にします。プロセスが実行中でデータが収集されている場合、その実験が終了し、データ収集は無効になります。プロセスが動作中でデータ収集が無効になっている場合、警告が出され、このサブコマンドは無視されます。プロセスが動作していない場合は、以降の実行のデータ収集が無効になります。
データ収集を有効にします。プロセスが動作していてデータ収集が無効であった場合、データ収集が有効になって新しい実験が開始されます。プロセスが動作中でデータ収集が有効になっている場合、警告が出され、このサブコマンドは無視されます。プロセスが動作していない場合は、以降の実行のデータ収集が有効になります。
プロセスの動作中、データ収集は何回でも有効にしたり、無効にしたりできます。データ収集を有効にするたびに、新しい実験が作成されます。
実験を開いたまま、データの収集を一時停止します。コレクタが一時停止している間、標本ポイントは記録されません。標本は一時停止の前に生成され、再開直後に別の標本が生成されます。データの収集がすでに一時停止されている場合、このサブコマンドは無視されます。
pause が実行されたあとに、データ収集を再開します。データ収集中は、このサブコマンドは無視されます。
name のラベルが付いた標本パケットを記録します。ラベルは、パフォーマンスアナライザの「イベント」タブで表示されます。
次のサブコマンドを、dbx 内で collector コマンドとともに使用して、実験の格納オプションを定義できます。実験がアクティブな場合は、警告メッセージが出力され、サブコマンドは無視されます。
実験を保管するためのモードを設定します。 mode に使用できる値は次のとおりです。
on - ロードオブジェクトを通常の方法で保管します。
off - ロードオブジェクトを保管しません。
copy - 通常の保管に加えて、ロードオブジェクトを実験にコピーします。
異なるマシンに実験を移動するか、別のマシンから実験を読み取る場合は、ロードオブジェクトのコピーを有効にする必要があります。実験がアクティブな場合、警告が出され、このコマンドは無視されます。このコマンドを使用しても、ソースファイルまたはオブジェクトファイルは実験にコピーされません。
記録するプロファイルデータの量を valueM バイトに制限します。この制限は、時間ベースのプロファイルデータ、ハードウェアカウンタオーバーフローのプロファイルデータ、および同期待ちのトレースデータの合計に適用されますが、標本ポイントには適用されません。この制限値は概数にすぎないので、この値を超えることは可能です。
制限に達すると、それ以上のプロファイルデータは記録されませんが、実験はオープンのままで標本ポイントの記録は継続します。
デフォルトでは、記録されるデータサイズに制限はありません。
実験の格納先を指定します。実験がアクティブな場合、警告が出力され、このコマンドは無視されます。option に使用できる値は次のとおりです。
directory directory-name - 実験と実験グループの格納先のディレクトリを設定します。指定したディレクトリが存在しない場合、警告が出され、このサブコマンドは無視されます。
experiment experiment-name - 実験の名前を設定します。指定した実験名の末尾が .er でない場合、警告が出され、このサブコマンドは無視されます。実験名とコレクタにおける実験名の取り扱いについての詳細は、「収集データの格納場所」を参照してください。
group group-name - 実験グループの名前を設定します。指定したグループ名の末尾が .erg でない場合、警告が出され、このサブコマンドは無視されます。グループがすでに存在する場合は、実験がグループに追加されます。ディレクトリ名が store directory サブコマンドで設定され、グループ名が絶対パスでない場合、グループ名の前にディレクトリ名が付きます。
次のサブコマンドを、dbx 内で collector コマンドとともに使用して、コレクタ設定と実験状態についてのレポートを取得できます。
すべてのコレクタ制御の、現在の設定を表示します。
Solaris プラットフォームでは、コレクタを使用して、実行中のプロセスからデータを収集できます。プロセスがすでに dbx の制御下にある場合は、プロセスを一時停止し、これまでに説明した方法を使用してデータ収集を有効にすることができます。実行中のプロセスからデータ収集を開始する操作は、Linux プラットフォームではサポートされていません。
プロセスが 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 |
実行中のプロセスに接続すると、そのプロセスが一時停止します。
プロセスへの接続についての詳細は、マニュアル『Oracle Solaris Studio 12.2: dbx コマンドによるデバッグ』を参照してください。
データの収集を開始します。
dbx から、collector コマンドを使用してデータ収集パラメータを設定し、cont コマンドを使用してプロセスを再開します。
プロセスから切り離します。
データの収集を完了したら、プログラムを一時停止し、dbx からプロセスを切り離します。
dbx から、次のように入力します。
(dbx) detach |
いずれかの種類のトレースデータを収集するには、プログラムを実行する前にコレクタライブラリ libcollector.so をプリロードする必要があります。ヒープトレースデータまたは同期待ちトレースデータを収集するには、er_heap.so および er_sync.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、er_sync.so、および er_heap.so をプリロードするための環境変数設定
環境変数 |
値 |
---|---|
LD_PRELOAD |
libcollector.so |
LD_PRELOAD |
er_heap.so |
LD_PRELOAD |
er_sync.so |
LD_LIBRARY_PATH |
/opt/solstudio12.2/prod/lib/dbxruntime |
LD_LIBRARY_PATH_32 |
/opt/solstudio12.2/prod/lib/dbxruntime |
LD_LIBRARY_PATH_64 |
/opt/solstudio12.2/prod/lib/v9/dbxruntime |
LD_LIBRARY_PATH_64 |
/opt/solstudio12.2/prod/lib/amd64/dbxruntime |
Oracle Solaris Studio ソフトウェアが /opt/solstudio12.2 にインストールされていない場合は、システム管理者に正しいパスを確認してください。LD_PRELOADにフルパスを設定することもできますが、そのようにすると、SPARC V9 の 64 ビットアーキテクチャーを使用するときに問題が発生する可能性があります。
実行が終了したら、LD_PRELOAD と LD_LIBRARY_PATH の設定を削除し、同じシェルから起動されるほかのプログラムが設定の影響を受けないようにしてください。
コレクタは、Message Passing Interface (MPI) を使用するマルチプロセスプログラムからパフォーマンスデータを収集できます。
コレクタは、Oracle Message Passing Toolkit 8 (以前の Sun HPC ClusterTools 8) とその更新をサポートしています。コレクタは、その他のバージョンの MPI も認識できます。collect を引数なしで実行すると、有効な MPI バージョンが一覧表示されます。
Oracle Message Passing Toolkit MPI ソフトウェアは http://www.oracle.com/us/products/tools/message-passing-toolkit-070499.html から入手できます。
MPI と MPI 規格については、MPI の Web サイト http://www.mcs.anl.gov/mpi/ を参照してください。Open MPI については、Web サイト http://www.open-mpi.org/ を参照してください。
MPI ジョブからデータを収集するには、collect コマンドを使用する必要があります。dbx collector サブコマンドは、MPI データ収集を開始するために使用できません。詳細は、「MPI 用の collect コマンドの実行」を参照してください。
collect コマンドを使用して、MPI アプリケーションのトレースとプロファイルを実行できます。
collect [collect-arguments] mpirun [mpirun-arguments] -- program-name [program-arguments] |
たとえば、次のコマンドは 16 の MPI プロセスそれぞれについて MPI トレースおよびプロファイルを実行し、データを単一の MPI 実験に格納します。
collect -M OMPT mpirun -np 16 -- a.out 3 5 |
-M OMPT オプションは、MPI プロファイルが実行されること、および Oracle Message Passing Toolkit が MPI バージョンであることを示します。
最初の収集プロセスは mpirun コマンドの形式を変更し、各 MPI プロセスについて適切な引数で collect コマンドを実行することを指定します。
program_name の直前にある ‐‐ 引数は、MPI プロファイルに必要となります。‐‐ 引数を含めないと、collect コマンドによりエラーメッセージが表示され、実験は収集されません。
mpirun コマンドを使用して MPI プロセス上で明示的に collect コマンドを生成する方法は、MPI トレースデータの収集ではサポートされなくなりました。ほかの種類のデータを収集する場合は、この方法を使用できます。
マルチプロセス環境は複雑になることがあるので、MPI プログラムからパフォーマンスデータを収集するときは、MPI 実験の格納に関するいくつかの問題に留意する必要があります。これら問題はデータ収集とデータ保存の効率、実験の命名に関わります。MPI実験を含む命名実験については、「収集データの格納場所」を参照。
パフォーマンスデータを収集する各 MPI プロセスは、独自のサブ実験を作成します。MPI プロセスは、実験を作成している間、実験ディレクトリをロックします。このため、ほかのすべての MPI プロセスは、ロックが解放されるまで待ってからそのディレクトリを使用する必要があります。実験は、すべての MPI プロセスからアクセス可能なファイルシステム上に格納します。
実験名を指定しなかった場合、デフォルトの実験名が使用されます。コレクタは、各 MPI ランクについて 1 つのサブ実験を実験の中に作成します。コレクタは MPI ランクを使用して、M_rm .er の形式でサブ実験名を構築します (m は MPI ランク)。
実験の完了後に、実験を別の場所へ移動する予定がある場合、collect コマンドで -A copy オプションを指定します。実験のコピーや移動には、UNIX® の cp または mv コマンドを使用しないで、第 8 章実験の操作で説明されている er_cp または er_mv コマンドを使用してください。
MPI トレースでは、各ノード上に一時ファイル /tmp/a.*.z が作成されます。これらのファイルは、MPI_finalize() 関数呼び出しによって削除されます。ファイルシステムに、実験のため十分な空き容量があることを確認します。実行時間の長い MPI アプリケーションのデータを収集する前に、短時間のテストを実行してファイルサイズを確認します。必要な空き容量を推定する方法について、「必要なディスク容量の概算」も参照してください。
MPI プロファイルは、オープンソースの VampirTrace 5.5.3 リリースがベースになっています。サポートされているいくつかの VampirTrace 環境変数に加えて、VT_STACKS を新たに認識します。この環境変数は、呼び出しスタックをデータに記録するかどうかを制御します。これらの変数の意味については、VampirTrace 5.5.3 のドキュメントを参照してください。
環境変数 VT_BUFFER_SIZE のデフォルト値は、MPI API トレースコレクタの内部バッファーを 64 M バイトに制限します。特定の MPI プロセスについてこの制限に到達した後、VT_MAX_FLUSHES 制限にまだ到達していなければ、バッファーはディスクにフラッシュされます。デフォルトでは、VT_MAX_FLUSHES は 0 です。この設定を行うと、MPI API トレースコレクタは、バッファーがいっぱいになるたびにバッファーをディスクにフラッシュします。VT_MAX_FLUSHES を正数に設定すると、フラッシュ回数が制限されます。バッファーがいっぱいになり、フラッシュできない場合、そのプロセスについては、それ以降イベントがトレースファイルに書き込まれなくなります。結果として実験が不完全なものとなり、場合によっては実験が読み取り不能になることがあります。
バッファーのサイズを変更するには、VT_BUFFER_SIZE 環境変数を使用します。この変数の最適値は、トレース対象のアプリケーションによって異なります。小さい値を設定すると、アプリケーションで利用できるメモリーが増えますが、MPI API トレースコレクタによってバッファーのフラッシュが頻繁に引き起こされます。このようなバッファーのフラッシュによって、アプリケーションの動作が大幅に変化する可能性があります。一方、2G バイトなどの大きい値を設定すると、MPI API トレースコレクタによるバッファーフラッシュは最小限に抑えられますが、アプリケーションで利用できるメモリーが減少します。バッファーとアプリケーションデータを保持するための十分なメモリーが利用できない場合、この設定によりアプリケーションの一部がディスクにスワップされ、アプリケーションの動作が大きく変化する可能性があります。
もう 1 つの重要な変数は VT_VERBOSE で、各種のエラーメッセージおよび状態メッセージを有効にします。問題が発生した場合、この変数を 2 以上に設定してください。
通常、MPI トレース出力データは mpirun ターゲットの終了時に後処理されます。処理されたデータファイルは実験に書き込まれ、後処理時刻情報が実験ヘッダーに書き込まれます。MPI トレースが -m off により明示的に無効になっている場合、MPI 後処理は行われません。後処理に失敗した場合、エラーが報告され、MPI タブと MPI トレースメトリックスは使用できなくなります。
mpirun ターゲットが実際に MPI を起動しない場合、実験は記録されますが、MPI トレースデータは生成されません。実験により、MPI 後処理エラーが報告され、MPI タブと MPI トレースメトリックスは使用できなくなります。
環境変数 VT_UNIFY が 0 に設定された場合、collect により後処理ルーチンは実行されません。後処理ルーチンは、実験で er_print または analyzer が初めて起動したときに実行されます。
コンピュータまたはノード間で実験のコピーあるいは移動を行うと、ソースファイル、または同じタイムスタンプを持つコピーにアクセスできないかぎり、注釈付きソースコードまたは注釈付き逆アセンブリコードのソース行を表示できません。注釈付きソースを表示するため、元のソースファイルへのシンボリックリンクを現在のディレクトリに置くことができます。また、「データ表示方法の設定」ダイアログボックスの設定を使用することもできます。「検索パス」タブ (「「検索パス」タブ」を参照) では、ソースファイルの検索に使用するディレクトリのリストを管理できます。「パスマップ」タブ (「「パスマップ」タブ」を参照) では、ファイルパスの先頭部分を、ある場所から別の場所へマッピングできます。
デフォルトでは、collect は ELF 実行可能ファイルをターゲットとする必要があり、このことを確認するためにターゲットをチェックします。ただし、このチェック機能を無効にして、ターゲットとして指定するスクリプト上で collect を実行することができます。
スクリプトプロファイリングは、試験段階の機能です。この実装は、以降のリリースで変更される可能性があります。
スクリプトをプロファイルするには、まず、環境変数 SP_COLLECTOR_SKIP_CHECKEXEC を設定して、ELF 実行可能ファイルのチェックを無効にします。
デフォルトでは、データは、スクリプトを実行するために起動したプログラムと、すべての派生プロセスで収集されます。特定のプロセスのみデータを収集するには、-F フラグを使用して、追跡する実行機能ファイルの名前を指定します。たとえば、スクリプト foo.sh をプロファイルするが、実行可能ファイル bar から主にデータを収集する場合は、次のコマンドを使用します。
csh の場合:
% setenv SP_COLLECTOR_SKIP_CHECKEXEC % collect -F =bar foo.sh |
sh の場合:
$ export SP_COLLECTOR_SKIP_CHECKEXEC $ collect -F =bar foo.sh |
スクリプトを実行するために起動した初期プロセスと、そのスクリプトから派生したすべての bar プロセスからデータを収集し、その他のプロセスからはデータを収集しません。
ppgsz コマンド上で collect を実行し、-F on または -F all フラグを使用すると、collect と ppgsz(1) を組み合わせて使用できます。親の実験は ppgsz 実行可能ファイルにあり、注目対象外です。パスに 32 ビットバージョンの ppgsz が存在し、実験が 64 ビットプロセスをサポートするシステムで実行されている場合、最初に 64 ビットバージョンを exec して _x1.er を作成します。この実行可能ファイルを fork し、_x1_f1.er を作成します。
子プロセスは、パスの最初のディレクトリに存在する名前付きターゲットの exec を試み、exec の試みが成功するまで、順に次のディレクトリについて同様な操作を行います。たとえば、3 番目の試みが成功した場合、最初の 2 つの派生実験には _x1_f1_x1.er および _x1_f1_x2.er という名前が付けられますが、これらは両方とも完全に空白です。ターゲット上の実験は、成功した 3 回目の exec によるもので、_x1_f1_x3.er という名前が付けられ、親の実験の下に格納されます。この実験は、test.1.er/_x1_f1_x3.er に対してアナライザまたは er_print ユーティリティーを起動することで直接処理可能です。
64 ビットの ppgsz が初期プロセスの場合、または 32 ビットの ppgsz が 32 ビットカーネル上で起動された場合、パスのプロパティーが前述の例と同じであると仮定して、実際のターゲットを exec する fork の子データは _f1.er にあり、実際のターゲットの実験は _f1_x3.er に存在します。