prime_pthr.c 的源代码如下所示:
1 /* 2 * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All Rights Reserved. 3 * @(#)prime_pthr.c 1.4 (Oracle) 10/03/26 4 */ 5 6 #include <stdio.h> 7 #include <math.h> 8 #include <pthread.h> 9 10 #define THREADS 4 11 #define N 10000 12 13 int primes[N]; 14 int pflag[N]; 15 int total = 0; 16 17 int is_prime(int v) 18 { 19 int i; 20 int bound = floor(sqrt(v)) + 1; 21 22 for (i = 2; i < bound; i++) { 23 /* no need to check against known composites */ 24 if (!pflag[i]) 25 continue; 26 if (v % i == 0) { 27 pflag[v] = 0; 28 return 0; 29 } 30 } 31 return (v > 1); 32 } 33 34 void *work(void *arg) 35 { 36 int start; 37 int end; 38 int i; 39 40 start = (N/THREADS) * (*(int *)arg); 41 end = start + N/THREADS; 42 for (i = start; i < end; i++) { 43 if ( is_prime(i) ) { 44 primes[total] = i; 45 total++; 46 } 47 } 48 return NULL; 49 } 50 51 int main(int argn, char **argv) 52 { 53 int i; 54 pthread_t tids[THREADS-1]; 55 56 for (i = 0; i < N; i++) { 57 pflag[i] = 1; 58 } 59 60 for (i = 0; i < THREADS-1; i++) { 61 pthread_create(&tids[i], NULL, work, (void *)&i); 62 } 63 64 i = THREADS-1; 65 work((void *)&i); 66 67 for (i = 0; i < THREADS-1; i++) { 68 pthread_join(tids[i], NULL); 69 } 70 71 printf("Number of prime numbers between 2 and %d: %d\n", 72 N, total); 73 74 return 0; 75 }
当代码包含竞争情况时,内存访问的顺序是不确定的,因此每次运行的计算结果会不同。
通过编译和运行示例可以看出,由于代码中存在数据争用,每次执行 prime_omp 或 prime_pthr 时都会产生不正确且不一致的结果。
在下面的示例中,键入粗体形式的命令以编译并运行 prime_omp 程序:
% cc -xopenmp=noopt -o prime_omp prime_omp.c -lm % % ./prime_omp Number of prime numbers between 2 and 10000: 1229 % ./prime_omp Number of prime numbers between 2 and 10000: 1228 % ./prime_omp Number of prime numbers between 2 and 10000: 1229 |
在下面的示例中,键入粗体形式的命令以编译并运行 prime_pthr 程序:
% cc -mt -o prime_pthr prime_pthr.c -lm % % ./prime_pthr Number of prime numbers between 2 and 10000: 1140 % ./prime_pthr Number of prime numbers between 2 and 10000: 1122 % ./prime_pthr Number of prime numbers between 2 and 10000: 1141 |
请注意每个程序的三次运行结果的不一致性。可能需要运行这些程序三次以上才能看到不一致的结果。
接下来将会校验代码并创建实验,以便可以找出发生数据争用的位置。