Oracle Solaris Studio 12.2:线程分析器用户指南

2.4.3.1 修复 prime_omp.c 中的错误

下面介绍如何修复 prime_omp.c 中的错误。有关所列的完整文件内容,请参见2.1.2 prime_omp.c 的源代码

将第 50 行和第 51 行移动到 critical(临界)段中,以便消除数组 primes[ ] 的元素上的数据争用。

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 行移动到两个 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     }

包含第 50 行和第 51 行的临界段将会消除数据争用,因为线程会使用互斥锁控制它们对 primes[ ] 数组的访问。但是,程序仍是错误的。两个线程可能会使用同一 total 值更新 primes[ ] 的同一元素,而 primes[ ] 的某些元素可能根本不会被赋值。

第二个数据争用(第 23 行中从 pflag[ ] 的读取与第 26 行中对 pflag[ ] 的写入之间的数据争用)实际上是良性争用,因为它并不会导致错误结果。没有必要修复良性数据争用。