Sun Studio 12:线程分析器用户指南

2.4.3.1 修复 omp_prime.c 中的错误

以下说明如何修复 omp_prime.c 中的错误。有关完整的文件列表,请参见 2.1.1 omp_prime.c 的完整列表

将第 45 行和第 46 行移动到临界段中,以便消除第 45 行上 total 的读取和第 46 行上 total 的写入之间的数据争用。临界段保护这两行并防止数据争用。以下是更正后的代码:

42      #pragma omp parallel for         .
43      for (i = 2; i < N; i++) {
44          if ( is_prime(i) ) {
                 #pragma omp critical

                 {          
 45                 primes[total] = i;
 46                 total++;
                 }
 47          }
 48      }

请注意,添加单个临界段还修复了 omp_prime.c 中的两个其他数据争用。它修复了第 45 行上 prime[] 的数据争用,以及第 46 行上 total 的数据争用。第 18 行上 pflag[] 的读取和第 21 行上 pflag[] 的写入之间的第四个数据争用实际上是良性争用,因为它不会导致不正确的结果。修复良性数据争用不是必需的。

还可以将第 45 行和第 46 行移动到临界段中,如下所示,但是此更改将无法更正程序:

42      #pragma omp parallel for         .
43      for (i = 2; i < N; i++) {
44          if ( is_prime(i) ) {
                 #pragma omp critical
                 {          
45                 primes[total] = i;
                 }
                 #pragma omp critical
                 {

46                 total++;
                 }
47          }
48      }

第 45 行和第 46 行周围的临界段消除了数据争用,因为线程不使用任何互斥锁控制其对 total 的访问。第 46 行周围的临界段确保 total 的计算值是正确的。但是,程序仍是不正确的。两个线程可能使用 total 的同一值更新 primes[] 的同一元素。此外,primes[] 中的某些元素可能根本未赋值。