この付録には、スレッドアナライザを使用するときのヒントが記されています。
実験結果の収集前にアプリケーションをコンパイルするためのヒント
アプリケーションバイナリを構築するときに –g コンパイラオプションを使用します。これにより、スレッドアナライザはデータの競合とデッドロックに関する行番号情報を報告できます。
アプリケーションバイナリを構築するときに、–xO3 より低い最適化レベルでコンパイルします。コンパイラの変換は、行番号情報を歪め、結果をわかりにくくさせることがあります。
スレッドアナライザは、メモリー割り当て APIに示すルーチンで割り込み処理をします。アーカイブバージョンのメモリー割り当てライブラリにリンクすると、誤検知のデータ競合が報告される場合があります。
実験結果を収集する前に、データの競合検出用アプリケーションを計測するためのヒント
次に示すように、データの競合の検出用にバイナリが計測されていない場合、collect -r race コマンドは、警告を発行します。
% collect -r races a.out WARNING: Target `a.out' is not instrumented for datarace detection; reported datarace data may be misleading
nm コマンドを使用して、tha ルーチンの呼び出しを検索することにより、データの競合の検出用にバイナリが計測されているかどうかを判断できます。名前が __tha_ で始まるルーチンが表示されたら、バイナリは計測されています。例出力は次のとおりです。
ソースレベルの計測:
% cc -xopenmp -g -xinstrument=datarace source.c % nm a.out | grep __tha_ [71] | 135408| 0|FUNC |GLOB |0 |UNDEF |__tha_get_stack_id [53] | 135468| 0|FUNC |GLOB |0 |UNDEF |__tha_src_read_w_frame [61] | 135444| 0|FUNC |GLOB |0 |UNDEF |__tha_src_write_w_frame
バイナリレベルの計測:
% cc -xopenmp -g source.c % discover -i datarace -o a.out.i a.out % nm a.out.i | grep __tha_ [88] | 0| 0|NOTY |GLOB |0 |UNDEF |__tha_read_w_pc_frame [49] | 0| 0|NOTY |GLOB |0 |UNDEF |__tha_write_w_pc_frame
データの競合およびデッドロックを検出するために、計測したアプリケーションを実行するためのヒント。
Oracle Solaris システムにすべての必須パッチがインストールされていることを確認します。collect コマンドは、見つからない必須パッチを一覧表示します。OpenMP アプリケーションの場合、libmtsk.so の最新バージョンが必要です。
計測は、実行時間の大幅な減速 (50 倍以上) と、メモリー消費量の増大を引き起こす可能性があります。より小さなデータセットを使用することにより、実行時間を減らそうと試みることができます。また、スレッド数を増やすことによって、実行時間を減らそうと試みることもできます。
データ競合を検出するには、アプリケーションが複数のスレッドを使用していることを確認します。OpenMP の場合、スレッド数は、環境変数 OMP_NUM_THREADS を、目的のスレッド数に設定し、環境変数 OMP_DYNAMIC を FALSE に設定することによって指定できます。
データの競合の報告のヒント
スレッドアナライザは、実行時にデータの競合を検出します。アプリケーションの実行時の動作は、使用される入力データセットとオペレーティングシステムのスケジュールによって異なります。異なるスレッド数と、異なる入力データセットで collect 下でアプリケーションを実行します。また、ルールがデータの競合を検出するチャンスを最大にするために、単一のデータセットでの実験を繰り返します。
スレッドアナライザは、単一のプロセスから生じた異なるスレッド間でのデータの競合を検出します。異なるプロセス間でのデータの競合は検出しません。
スレッドアナライザは、データの競合でアクセスされた変数の名前を報告しません。ただし、2 つのデータの競合アクセスが行われたソース行を調べ、このソース行で変数が書き込まれ、読み取られたかを判断することによって、変数の名前を判別できます。
場合によっては、スレッドアナライザは、プログラムで実際には起きなかったデータの競合を報告することがあります。これらのデータの競合は誤検知と呼ばれます。これは通常、ユーザーが実装した同期が使用される場合や、メモリーがスレッド間でリサイクルされる場合に起こります。たとえば、スピンロックを実装するハンドコーディングされたアセンブリがコードに含まれる場合、スレッドアナライザはこれらの同期ポイントを認識しません。スレッドアナライザのユーザー API に対する呼び出しをソースコードに挿入して、ユーザー定義の同期についてスレッドアナライザに通知します。詳細は、誤検知とAppendix A, スレッドアナライザで認識される APIを参照してください。
ソースレベルの計測を使用して報告されたデータの競合とバイナリレベルの計測を使用して報告されたデータの競合は、同じでない場合があります。バイナリレベルの計測の場合、それらがプログラム内で静的にリンクされているか、dlopen() によって動的に開かれているかにかかわらず、共有ライブラリは開いているときに、デフォルトで計測されます。ソースレベルの計測の場合、ライブラリは、そのソースが –xinstrument=datarace でコンパイルされている場合にのみ計測されます。