在for循环中使用OpenMP会导致输出错误

时间:2017-09-29 16:41:20

标签: c performance math parallel-processing openmp

我正在编写一个程序来使用梯形和中点规则集成一个函数。我想使用并行来加速执行。在下面的代码中,我假设因为每个集成独立于下一个,这对于并行处理是理想的,但是当使用OpenMP时输出是不正确的,尽管速度更快。

我尝试使用" #pragma omp parallel private"对于所使用的变量,但是以单线程速度产生正确的输出。使用" #pragma omp critical"。

时也会发生同样的事情

为什么会这样?

提前感谢您的任何建议/帮助。

#include <stdio.h>
#include <math.h>
#include <omp.h>

#define lowerbound -3
#define upperbound -1

// The function to be integrated
long double f(long double x) {
    return ((6 * pow(x,-2) + 5 * pow(x,-7) - 1) / (2 * sin(x) - pow(tan(x),2)) + 2);
}

// Trapezium integration
long double trapezium(unsigned long n) {
    // let h = trapezium widths
    long double h = ((upperbound - lowerbound) / (n * 1.0f));

    // add f0 and fn
    long double output = f(lowerbound) + f(upperbound);

    // add f1 to fn-1
    #pragma omp parallel for
    for (unsigned long i=1; i < n; i++) {
        // h multiplied by i gives the x coordinate to find the f(x) of
        long double val = f(lowerbound + h * i) * 2;
        output += val;
    }

    // multiply by half h as per trapezium rule
    return ((h/2) * output);
}

// Midpoint integration
long double midpoint(unsigned long n) {

    // let h = width
    long double h = ((upperbound - lowerbound) / (n * 1.0f));

    long double output = 0;

    // add middle rectangles
    #pragma omp parallel for
    for (unsigned long i=0; i < n; i++) {
        // adding h2 due to inital offset of centres of rectangles, multiplying by h to get area
        long double val = f(lowerbound + h/2 + h * i) * h;
        output += val;
    }

    return output;
}



int main() {
    omp_set_num_threads(8);

    // Print answers

    for (int i=1; i < 30; i++) {
        printf("%lu", (unsigned long)pow(2,i));
        printf("    ");
        printf("%20.20Lf", trapezium(pow(2,i)));
        printf("    ");
        printf("%20.20Lf\n", midpoint(pow(2,i)));
    }
}

0 个答案:

没有答案