下面介绍如何修复 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[ ] 的写入之间的数据争用)实际上是良性争用,因为它并不会导致错误结果。没有必要修复良性数据争用。