如何使用 C++ 和 OpenMP 并行计算数组的总和?

How to calculate the sum of an array in parallel using C++ and OpenMP?

我的任务是使用 C++ 和 OpenMP 并行化在我下面的代码中看到的数组的创建、加倍和求和。但是,我无法使总和正确地并行工作。这是我第一次使用 OpenMP,而且我对 C++ 也很陌生。我已经尝试了在下面的代码中可以看到的内容以及其他变体(在 for 循环之外有总和,并行定义一个总和以添加到全局总和,我已经尝试了建议 here, ETC)。总和 应该 4.15362e-14,但是当我使用多个线程时,每次都会得到不同的结果,这些结果是不正确的。实现这一目标的正确方法是什么?

P.S。到目前为止,我们只学到了关键、大师、障碍和单一结构,所以如果答案不包括任何其他结构,我将不胜感激。谢谢!

#include <iostream>
#include <cmath>
#include <omp.h>

using namespace std;

int main()
{
    const int size = 256;
    double* sinTable = new double[256];
    double sum = 0.0;

    // parallelized
    #pragma omp parallel
    {
        for (int n = 0; n < size; n++)
        {
            sinTable[n] = std::sin(2 * M_PI * n / size);  // calculate and insert element into array  
            sinTable[n] = sinTable[n] * 2;  // double current element in array
            #pragma omp critical
            sum += sinTable[n];  // add element to total sum (one thread at a time)
        }
    }
    // print sum and exit
    cout << "Sum: " << sum << endl;
    return 0;
}

不幸的是,您的代码不正确,因为您 运行 for 循环线程数而不是分配工作。你应该使用:

#pragma omp parallel for

在线程之间分配工作。 另一种选择是使用缩减:

int main()
{
    const int size = 256;
    const double step = (2.0 * M_PI) / static_cast<double>(size); 
    double* sinTable = new double[size];
    double sum = 0.0;

    // parallelized
    #pragma omp parallel for reduction(+:sum)    
    for (int n = 0; n < size; n++)
    {
        sinTable[n] = std::sin( static_cast<double>(n) * step);   // calculate and insert element into array  
        sinTable[n] = sinTable[n] * 2.0;  // double current element in array
        sum += sinTable[n];  // add element to total sum (one thread at a time)
    }
    
    // print sum and exit
    cout << "Sum: " << sum << endl;
    delete[] sinTable;
    return 0;
}

请注意,理论上总和应为零。您获得的值取决于相加的顺序,因此可能会因四舍五入而略有不同。

size=256  sum(openmp)=2.84217e-14 sum(no openmp)= 4.15362e-14
size=512  sum(openmp)=5.68434e-14 sum(no openmp)= 5.68434e-14
size=1024 sum(openmp)=0           sum(no openmp)=-2.83332e-14

这里是link到CodeExplorer