1

my task is to parallelize the creation, doubling, and summation of the array seen in my code below using C++ and OpenMP. However, I cannot get the summation to work in parallel properly. This is my first time using OpenMP, and I am also quite new to C++ as well. I have tried what can be seen in my code below as well as other variations (having the sum outside of the for loop, defining a sum in parallel to add to the global sum, I have tried what is suggested here, etc). The sum should be 4.15362e-14, but when I use multiple threads, I get different results each time that are incorrect. What is the proper way to achieve this?

P.S. We have only been taught the critical, master, barrier, and single constructs thus far so I would appreciate if answers would not include any others. Thanks!

#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;
}
1
  • 1
    In case you want to use new, don't forget to delete the resource when you no longer need it. Otherwise you will introduce memory leaks. Commented Oct 4, 2021 at 4:43

1 Answer 1

2

Unfortunately your code is not OK, because you run the for loop number of thread times instead of distributing the work. You should use:

#pragma omp parallel for

to distribute the work among threads. Another alternative is to use reduction:

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;
}

Note that in theory the sum should be zero. The value you obtain depends on the order of additions, so slight difference can be observed due to rounding errors.

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

Here is the link to CodeExplorer.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.