maomaoyu
maomaoyu

Reputation: 1

OpenMP doesn't give right result and different time

I am new to OpenMP and now I'm studying the usage of atomic. I had a different result and time each run. Sometimes about a minute sometimes about 19 seconds.

Below is my code:

#include <iostream>
#include<iomanip>
#include<cmath>
#include<omp.h>
#include"KiTimer.h"

int main() 
{
    using namespace std;

    const int NUM_REPEAT = 100000000;
    KiTimer timer;
    timer.MakeTimer(0, "ADD");
    timer.Start();

    double sum = 0., x = 0.;
#pragma omp parallel
    {
#pragma omp single
        cout << "Thread num:" << omp_get_num_threads() << endl;
#pragma omp for private(x)
        for (int i = 0; i < NUM_REPEAT; i++) {
            x = sqrt(i);
#pragma omp atomic
            sum += x;
        }
    }

    cout << setprecision(20) << "total:" << sum << endl;
    timer.Stop();
    timer.Print();
    return 0;
}

Here are the results from three different test runs:

  1. First Result:

enter image description here

  1. Second Result:

enter image description here

  1. Third Result:

enter image description here

Upvotes: 0

Views: 176

Answers (1)

Adriel Jr
Adriel Jr

Reputation: 2681

The correct way of doing sum with OMP is:

#pragma omp for reduction(+:sum)

instead of

#pragma omp for private(x)
...
#pragma omp atomic

The atomic clause as far as I remember adds a big overhead when executed too often (as it is the case).

Also, the scope of x can be greatly reduced, simplifying the code: no need to use private.

About the different result, that is normal since you are adding floating point numbers in different orders in different executions. It is more of a problem when operating big numbers with small numbers since they need to be normalized when operating and will loose precision. In the case of doubles, the precision is 15 digits, so if you add 1000000000000000 + 1, the result will still be 1000000000000000, even if you do it many times.

Upvotes: 1

Related Questions