我正在尝试使用OpenMP使以下程序并行:
#include <time.h>
// Program computes the total number of primes larger than 100000001 and smaller than 16000001.
main() {
int number = 100000001;
int primes[20];
int i, j, is_prime, index = 0, nprimes = 0;
time_t start_time, end_time;
start_time = time(NULL);
for (i = 0; i < 3000000; i++) {
// get the next number to check if it is a prime
number += 2;
is_prime = 1;
for (j = 2; j < 10001; j++) {
if ((number % j) == 0) {
is_prime = 0;
break;
}
}
// f0und a prime number. Count it and save the first 20 primes
if (is_prime) nprimes++;
if (is_prime && (index < 20)) {
primes[index] = number;
index++;
}
}
for (i = 0; i < 20; i++)
printf("%d is prime\n", primes[i]);
end_time = time(NULL);
printf("number of primes = %d, elapsed time is %d seconds\n", nprimes, end_time - start_time);
}
我所做的是:
#include <stdio.h>
#include <time.h>
#include <omp.h>
#define CHUNKSIZE 750000
//#define CHUNKSIZE2 2500
// Program computes the total number of primes larger than 100000001 and smaller than 16000001.
int main() {
int number = 100000001;
int primes[20];
int i, j, is_prime, index = 0, nprimes = 0;
time_t start_time, end_time;
start_time = time(NULL);
int chunk = CHUNKSIZE;
//int chunk2 = CHUNKSIZE2;
#pragma omp parallel shared(number, index, nprimes, chunk) private(i, j, is_prime)
{
#pragma omp parallel for schedule (dynamic, chunk)
for (i = 0; i < 3000000; i++) {
// get the next number to check if it is a prime
number += 2;
is_prime = 1;
//#pragma omp parallel for schedule (dynamic, chunk2)
for (j = 2; j < 10001; j++) {
if ((number % j) == 0) {
is_prime = 0;
break;
}
}
// f0und a prime number. Count it and save the first 20 primes
if (is_prime) nprimes++;
if (is_prime && (index < 20)) {
primes[index] = number;
index++;
}
}
for (i = 0; i < 20; i++)
printf("%d is prime\n", primes[i]);
end_time = time(NULL);
printf("number of primes = %d, elapsed time is %d seconds\n", nprimes, end_time - start_time);
//return 0;
}
我尝试了很多东西,但大多数都给了我更长时间或者同样的时间!!!
答案 0 :(得分:1)
number
变量全局递增,因此创建了障碍;没有计算可以并行完成,每个线程必须等待前一个线程结束才能使number+=2
部分保持一致。
您可以通过创建另一个特定于线程的变量(此处为n
)来避免这种情况,该变量的值基于循环索引(i
)
一个pragma omp并行就足够了:
#include <stdio.h>
#include <time.h>
#include <omp.h>
#define CHUNKSIZE 750000
//#define CHUNKSIZE2 2500
// Program computes the total number of primes larger than 100000001 and smaller than 16000001.
int main() {
int number = 100000001;
int n;
int primes[20];
int i, j, is_prime, index = 0, nprimes = 0;
time_t start_time, end_time;
start_time = time(NULL);
int chunk = CHUNKSIZE;
//int chunk2 = CHUNKSIZE2;
#pragma omp parallel for private(n, is_prime, j)
for (i = 0; i < 300000; i++) {
// get the next number to check if it is a prime
//number += 2;
n = number + i*2;
is_prime = 1;
//#pragma omp parallel for schedule (dynamic, chunk2)
for (j = 2; j < 10001; j++) {
if ((n % j) == 0) {
is_prime = 0;
break;
}
}
// f0und a prime number. Count it and save the first 20 primes
if (is_prime) nprimes++;
if (is_prime && (index < 20)) {
primes[index] = n;
index++;
}
}
for (i = 0; i < 20; i++)
printf("%d is prime\n", primes[i]);
end_time = time(NULL);
printf("number of primes = %d, elapsed time is %d seconds\n", nprimes, end_time - start_time);
//return 0;
}
使用gcc和精简计算的结果,以避免等待太多:
$ gcc -fopenmp -o tt tt.c
$ time OMP_NUM_THREADS=1 ./tt
100000007 is prime
[...]
100000393 is prime
number of primes = 326390, elapsed time is 21 seconds
real 0m20.507s
user 0m20.492s
sys 0m0.001s
$ time OMP_NUM_THREADS=8 ./tt
101500027 is prime
[...]
105250049 is prime
number of primes = 325580, elapsed time is 3 seconds
real 0m3.041s
user 0m24.284s
sys 0m0.002s