スレッドアナライザは、Oracle Developer Studio パフォーマンスアナライザが使用するものと同じ "収集-分析" モデルに従います。
スレッドアナライザを使用するには、次の 3 つの手順を行います。
プログラムでデータの競合の検出を可能にするには、実行時にメモリーアクセスをモニターするコードをあらかじめ計測しておく必要があります。計測機構の組み込みは、アプリケーションのソースコードまたはアプリケーションバイナリで行えます。このチュートリアルでは、プログラムを計測する両方のメソッドの使用方法を示します。
ソースコードを計測するには、特別なコンパイラオプション -xinstrument=datarace を使ってアプリケーションをコンパイルする必要があります。このオプションは、データの競合の検出用に生成したコードを計測するようにコンパイラに指示します。
-xinstrument=datarace コンパイラオプションを、プログラムのコンパイルに使用する既存のオプションセットに追加します。
このチュートリアル用にソースコードを計測するには、次のコマンドを使用できます。
% cc -xinstrument=datarace -g -xopenmp=noopt -o prime_omp_inst prime_omp.c -lm
% cc -xinstrument=datarace -g -o prime_pthr_inst prime_pthr.c -lm
例では、バイナリが計測済みバイナリであることがわかるように、出力ファイルの末尾に _inst と指定されています。これは必須ではありません。
ソースコードの代わりにプログラムのバイナリコードを計測するには、discover ツールを使用する必要があり、このツールは、Oracle Developer Studio に含まれ、discover(1) のマニュアルページとOracle Developer Studio 12.5: Discover および Uncover ユーザーズガイドに記載されています。
チュートリアルの例では、次のコマンドを入力してコードをコンパイルします。
% cc -xopenmp=noopt -g -o prime_omp prime_omp.c -lm
% cc -g -O2 -o prime_pthr prime_pthr.c -lm
続いて、discover を、作成した prime_omp および prime_pthr 最適化済みバイナリで実行します。
% discover -i datarace -o prime_omp_disc prime_omp
% discover -i datarace -o prime_pthr_disc prime_pthr
これらのコマンドは計測済みバイナリ、prime_omp_disc および prime_pthr_disc を作成するので、これらのバイナリを collect で使用して、スレッドアナライザで検証する実験を作成できます。
-r race フラグを付けて collect コマンドを使用してプログラムを実行し、プロセスの実行中にデータ競合の検出実験を作成します。OpenMP プログラムの場合、使用されるスレッド数が 1 より大きいことを確認してください。チュートリアルの例では 4 つのスレッドが使用されます。
ソースコードを計測して作成したバイナリから実験を作成するには、次のスレッドを使用します。
% collect -r race -o prime_omp_inst.er prime_omp_inst
% collect -r race -o prime_pthr_inst.er prime_pthr_inst
discover ツールを使用して作成したバイナリから実験を作成するには、次のようにします。
% collect -r race -o prime_omp_disc.er prime_omp_disc
% collect -r race -o prime_pthr_disc.er prime_pthr_disc
データの競合を検出する可能性を高めるには、-r race フラグ付きで collect を使用して、複数のデータの競合の検出実験を作成することをお勧めします。実験ごとに異なるスレッド数と異なる入力データを使用してください。
たとえば prime_omp.c では、スレッド数は次の行で設定されます。
#define THREADS 4
この 4 を 1 より大きな他の整数 (たとえば 8) に変えると、スレッド数を変更できます。
prime_omp.c の次の行は、2 ~ 3000 の素数を検出するようにプログラムを制限します。
#define N 3000
N の値を変更して別の入力データを指定すると、プログラム作業量を増減できます。
スレッドアナライザ、パフォーマンスアナライザ、er_print ユーティリティーで、データ競合の検出実験を検証できます。スレッドアナライザおよびパフォーマンスアナライザはどちらも GUI インタフェースを表示します。スレッドアナライザはデフォルトビューの簡略セットを表示しますが、それ以外はパフォーマンスアナライザと同じです。
スレッドアナライザを開始するには、次のコマンドを入力します。
% tha
スレッドアナライザをはじめて起動すると、開始画面が表示されます。
スレッドアナライザには、メニューバー、ツールバー、左側にデータビューを選択できる垂直のナビゲーションバーが表示されます。
デフォルトでは次のデータビューが表示されます。
「概要」画面には、ロードされた実験のメトリックの概要が表示されます。
「競合」ビューには、プログラム内で検出されたデータ競合と関連する呼び出しスタックトレースの一覧が表示されます。「競合」ビューである項目を選択すると、選択したデータ競合または呼び出しスタックトレースの詳細情報が「競合の詳細」ウィンドウに表示されます。
「デュアルソース」ビューには、選択したデータの競合の 2 つのアクセスに対応する 2 つのソースの位置が表示されます。データの競合アクセスが起きたソース行が強調表示されます。
「実験」ビューには、実験でのロードオブジェクトが表示され、エラーおよび警告メッセージが一覧表示されます。
「詳細ビュー」オプションメニューでほかのビューを表示できます。
er_print ユーティリティーは、コマンド行インタフェースを表示します。インタラクティブセッションで er_print ユーティリティーを使用して、セッション中にサブコマンドを指定します。コマンド行オプションを使用して、インタラクティブでない方法でもサブコマンドを指定できます。
次のサブコマンドは、er_print ユーティリティーで競合を調べるときに役立ちます。
–races
これは、実験で明らかになったデータの競合をすべて報告します。(er_print) プロンプトで races と指定するか、er_print コマンド行で –races と指定します。
–rdetail race_id
これにより、指定した race_id を持つデータの競合に関する詳細な情報が表示されます。(er_print) プロンプトで rdetail と指定するか、er_print コマンド行で –rdetail と指定します。指定した race_id が all の場合、すべてのデータの競合に関する詳細情報が表示されます。それ以外では、最初のデータの競合を表す 1 などの単一の競合番号を指定します。
–header
これは、実験に関する記述的情報を表示し、すべてのエラーまたは警告を報告します。(er_print) プロンプトで header と指定するか、コマンド行で –header と指定します。
詳細は、collect(1)、tha(1)、analyzer(1)、および er_print(1) のマニュアルページを参照してください。