この節では、er_print コマンド行インタフェースとスレッドアナライザ GUI の両方を使用して、検出されたすべてのデータ競合に関する次の情報を表示する方法を説明します。
データ競合の一意の ID。
データ競合に関係する仮想アドレス (Vaddr
)。
複数の仮想アドレスがある場合は、括弧で囲って複数のアドレスと表示されます。
2 つの異なるスレッドによる仮想アドレス (Vaddr
) へのメモリーアクセス。アクセスの種類 (読み取り/書き込み) が、ソースコード内のアクセスが発生した関数、オフセット、および行番号とともに表示されます。
データ競合に関係する総トレース数。各トレースは、2 つのデータ競合アクセスの発生した時点でのスレッド呼び出しスタックのペアを表します。GUI を使用している場合、個別にトレースを選択すると、「競合の詳細」タブに 2 つの呼び出しスタックが表示されます。er_print ユーティリティーを使用している場合は、rdetail コマンドによって 2 つの呼び出しスタックが表示されます。
% cc -xopenmp=noopt omp_prime.c -lm -xinstrument=datarace % collect -r race a.out | sort -n 0 0 0 0 0 0 0 0 0 0 ... 0 0 実験データベース test.1.er の作成中 ... Number of prime numbers between 2 and 3000: 429 2 3 5 7 11 13 17 19 23 29 31 37 41 47 53 59 61 67 71 73 ... 2971 2999 % er_print test.1.er (er_print) races 総競合数: 4 実験: test.1.er 競合 #1, Vaddr: 0xffbfeec4 アクセス 1: 読み取り, main -- 行 42 からの MP doall [_$d1A42.main] + 0x00000060, 行 45 "omp_prime.c" アクセス 2: 書き込み, main -- 行 42 からの MP doall [_$d1A42.main] + 0x0000008C, 行 46 "omp_prime.c" 総トレース数: 2 競合 #2, Vaddr: 0xffbfeec4 アクセス 1: 書き込み, main -- 行 42 からの MP doall [_$d1A42.main] + 0x0000008C, 行 46 "omp_prime.c" アクセス 2: 書き込み, main -- 行 42 からの MP doall [_$d1A42.main] + 0x0000008C, 行 46 "omp_prime.c" 総トレース数: 1 競合 #3, Vaddr: (Multiple Addresses) アクセス 1: 書き込み, main -- 行 42 からの MP doall [_$d1A42.main] + 0x0000007C, 行 45 "omp_prime.c" アクセス 2: 書き込み, main -- 行 42 からの MP doall [_$d1A42.main] + 0x0000007C, 行 45 "omp_prime.c" 総トレース数: 1 競合 #4, Vaddr: 0x21418 アクセス 1: 読み取り, is_prime + 0x00000074, 行 18 "omp_prime.c" アクセス 2: 書き込み, is_prime + 0x00000114, 行 21 "omp_prime.c" 総トレース数: 1 (er_print)
次のスクリーンショットは、omp_primes.c で検出された競合の、スレッドアナライザ GUI での表示例です。GUI を呼び出して、実験データを読み込むコマンドは tha test.1.er になっています。
omp_primes.c には、4 つのデータ競合があります。
競合番号 1: 行 45 の total の読み取りと行 46 の total への書き込みとのデータ競合。
競合番号 2: 行 46 の total への書き込みと同一行での total への別の書き込みとのデータ競合。
競合番号 3: 行 45 の primes[]
への書き込みと同一行での primes[]
への別の書き込みとのデータ競合。
競合番号 4: 行 18 の pflag[]
の読み取りと行 21 の pflag[]
への書き込みとのデータ競合。
% cc pthr_prime.c -lm -mt -xinstrument=datarace . % collect -r on a.out | sort -n 実験データベース test.2.er の作成中 ... of type "nfs", which may distort the measured performance. 0 0 0 0 0 0 0 0 0 0 ... 0 0 実験データベース test.2.er の作成中 ... Number of prime numbers between 2 and 3000: 328 751 757 761 773 797 809 811 821 823 827 829 839 853 857 859 877 881 883 887 907 ... 2999 2999 % er_print test.2.er (er_print) races 総競合数: 6 実験: test.2.er 競合 #1, Vaddr: 0x218d0 アクセス 1: 書き込み, work + 0x00000154, 行 40 "pthr_prime.c" アクセス 2: 書き込み, work + 0x00000154, 行 40 "pthr_prime.c" 総トレース数: 3 競合 #2, Vaddr: 0x218d0 アクセス 1: 読み取り, work + 0x000000CC, 行 39 "pthr_prime.c" アクセス 2: 書き込み, work + 0x00000154, 行 40 "pthr_prime.c" 総トレース数: 3 競合 #3, Vaddr: 0xffbfeec4 アクセス 1: 書き込み, main + 0x00000204, 行 55 "pthr_prime.c" アクセス 2: 読み取り, work + 0x00000024, 行 35 "pthr_prime.c" 総トレース数: 2 競合 #4, Vaddr: (Multiple Addresses) アクセス 1: 書き込み, work + 0x00000108, 行 39 "pthr_prime.c" アクセス 2: 書き込み, work + 0x00000108, 行 39 "pthr_prime.c" 総トレース数: 1 競合 #5, Vaddr: 0x23bfc アクセス 1: 書き込み, is_prime + 0x00000210, 行 22 "pthr_prime.c" アクセス 2: 書き込み, is_prime + 0x00000210, 行 22 "pthr_prime.c" 総トレース数: 1 競合 #6, Vaddr: 0x247bc アクセス 1: 書き込み, work + 0x00000108, 行 39 "pthr_prime.c" アクセス 2: 読み取り, main + 0x00000394, 行 65 "pthr_prime.c" 総トレース数: 1 (er_print)
次のスクリーンショットは、pthr_primes.c で検出された競合の、スレッドアナライザ GUI での表示例です。GUI を呼び出して、実験データを読み込むコマンドは tha test.2.er になっています。
pthr_prime.c には、6 つのデータ競合があります。
競合番号 1: 行 40 の total への書き込みと同一行での total への別の書き込みとのデータ競合。
競合番号 2: 行 39 の total の読み取りと行 40 の total への書き込みとのデータ競合。
競合番号 3: 行 55 の i への書き込みと行 35 の i の読み取りとのデータ競合。
競合番号 4: 行 39 の primes[]
への書き込みと同一行での primes[]
への別の書き込みとのデータ競合。
競合番号 5: 行 22 の pflags[]
への書き込みと同一行での pflags[]
への別の書き込みとのデータ競合。
競合番号 6: 行 39 の primes[]
への書き込みと行 65 の primes[]
の読み取りとのデータ競合。
GUI の利点は、データ競合に関係する 2 つのソース位置を横に並べて見られることです。たとえば「競合」タブで pthr_prime.c の競合番号 6 を選択し、「デュアルソース」タブをクリックすると、次のような画面になります。
競合番号 6 (行 39) の最初のアクセスが競合のソースの上の区画、同じデータ競合の 2 つ目のアクセスが下の区画に表示されます。このデータ競合アクセスが発生したソース行 39 および 65 は強調表示されます。デフォルトメトリック (「排他的競合アクセス」メトリック) は各ソース行の左側に表示されます。このメトリックは、その行についてデータ競合アクセスが報告された回数を示します。