【问题标题】:parallelizing c code using openmp使用openmp并行化c代码
【发布时间】:2013-10-17 19:21:57
【问题描述】:

我正在尝试使用 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;
}

我尝试了很多东西,但大多数都给了我更长或相同的时间!!!

【问题讨论】:

    标签: c parallel-processing openmp


    【解决方案1】:

    number 变量全局递增,因此创建了一个屏障;不能并行计算,每个线程都必须等待前一个线程结束,这样number+=2部分是一致的。

    您可以通过创建另一个特定于线程的变量(此处为n)来规避此问题,其值基于循环索引(i

    一个pragma omp parallel for 就足够了:

    #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
    

    【讨论】:

      猜你喜欢
      • 2012-03-27
      • 2015-08-02
      • 1970-01-01
      • 2021-04-28
      • 1970-01-01
      • 1970-01-01
      • 2016-11-14
      • 2015-05-25
      • 2021-10-18
      相关资源
      最近更新 更多