Oracle Solaris Studio 12.2: スレッドアナライザユーザーズガイド

2.4.3.1 prime_omp.c でのバグの修正

ここでは、prime_omp.c でのバグを修正する方法について説明します。完全なファイルのリストについては、「「2.1.2 prime_omp.c のソースコード」」を参照してください。

配列 primes[ ] の要素でのデータの競合を削除するために、行 50 および 51 を critical セクションに移します。

47      #pragma omp parallel for
48      for (i = 2; i < N; i++) {
49          if ( is_prime(i) ) {
                 #pragma omp critical

                 {
50                  primes[total] = i;
51                  total++;
                 }
52          }
53     }

また、次のように行 50 および 51 を 2 つの critical セクションに移すこともできますが、この変更ではプログラムを修正できません。

47      #pragma omp parallel for
48      for (i = 2; i < N; i++) {
49          if ( is_prime(i) ) {
                 #pragma omp critical
                 {
50                  primes[total] = i;
                 }
                 #pragma omp critical
                 {
51                  total++;
                 }
52          }
53     }

スレッドは、排他的ロックを使用して primes[ ] 配列へのアクセスを制御しているので、行 50 および 51 の critical セクションによってデータの競合が取り除かれます。ただし、プログラムはまだ正しくありません。2 つのスレッドは、同じ合計値を使用して primes[ ] の同じ要素を更新する可能性があり、primes[ ] の要素の中には、値がまったく割り当てられないものが生じる可能性があります。

行 23 での pflag[ ] からの読み取りと、行 26 での pflag[ ] への書き込みとの 2 番目のデータの競合は間違った結果を招かないので、実際には影響のない競合です。影響のないデータの競合の修正は必須ではありません。