Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenMP program is slower than sequential one

When I try the following code

double start = omp_get_wtime();

long i;

#pragma omp parallel for
    for (i = 0; i <= 1000000000; i++) {
        double x = rand();
    }

    double end = omp_get_wtime();

    printf("%f\n", end - start);

Execution time is about 168 seconds, while the sequential version only spends 20 seconds.

I'm still a newbie in parallel programming. How could I get a parallel version that's faster that the sequential one?

like image 343
Islam Hassan Avatar asked May 16 '12 18:05

Islam Hassan


People also ask

Is OpenMP parallel or concurrent?

OpenMP versions 2.0 and 2.5, which are supported by the Microsoft C++ compiler, are well-suited for parallel algorithms that are iterative; that is, they perform parallel iteration over an array of data.

Is OpenMP multithreaded?

The OpenMP standard was formulated in 1997 as an API for writing portable, multithreaded applications. It started as a Fortran-based standard, but later grew to include C and C++. The current version is OpenMP 2.0, and Visual C++® 2005 supports the full standard.

How do I avoid race conditions in OpenMP?

Avoiding Race Conditions One approach to avoiding this program's race condition is to use a separate local variable integral for each thread instead of a global variable that is shared by all the threads.


1 Answers

The random number generator rand(3) uses global state variables (hidden in the (g)libc implementation). Access to them from multiple threads leads to cache issues and also is not thread safe. You should use the rand_r(3) call with seed parameter private to the thread:

long i;
unsigned seed;

#pragma omp parallel private(seed)
{
    // Initialise the random number generator with different seed in each thread
    // The following constants are chosen arbitrarily... use something more sensible
    seed = 25234 + 17*omp_get_thread_num();
    #pragma omp for
    for (i = 0; i <= 1000000000; i++) {
       double x = rand_r(&seed);
    }
}

Note that this will produce different stream of random numbers when executed in parallel than when executed in serial. I would also recommend erand48(3) as a better (pseudo-)random number source.

like image 132
Hristo Iliev Avatar answered Sep 17 '22 13:09

Hristo Iliev