2

Im trying to parallelize my code with openmp.

I have a global vector, so i can excess it with my functions. Is there a way that i can asign a copy of the vector to every thread so they can do stuff with it? Here is some pseudocode to describe my problem:

double var = 1;
std::vector<double> vec;

void function()
{
    vec.push_back(var);
    return;
}


int main()
{
    omp_set_num_threads(2);

    #pragma omp parallel 
    {
        #pragma omp for private(vec)
        for (int i = 0; i < 4; i++)
        {        
            function(); 
        }
    }
    return 0;
}

Notes:

  • i want each tread to have an own vector, to safe specific values, which later only the same thread needs to excess
  • each thread calls a function (sometimes its the same) which then does some work on the vector (changing specific values)
  • (in my original code there are many vectors and functions, ive just tried to break the problem down)

Ive tried #pragma omp threadprivate(), but that only works for varibles and not for vectors. Also redeclaring the vector inside the parallel region doesnt help, as my function always works with the global vector, which then leads to problems when different treads call it at the same time.

2
  • 1
    Pass vec by value to function? Commented Jun 25, 2022 at 15:14
  • Mutated global variables should avoided like the plague in parallel applications. They cause a lot of problem starting from the hidden dependency which tends to cause race conditions and performance issues. In fact, they are already considered bad in term of software engineering in sequential code. Commented Jun 25, 2022 at 15:56

1 Answer 1

1

Is there a way that I can assign a copy of the vector to every thread so they can do stuff with it?

Yes, the firstprivate clause does this:

The firstprivate clause declares one or more list items to be private to a task, and initializes each of them with the value that the corresponding original item has when the construct is encountered.

So, it creates a private copy of the variable for each thread, but the scope of this private variable is the structured block following the OpenMP construct. Outside this block you access the global variable:

#pragma omp ... firstprivate(vec)
{                
      vec.push_back(...);  // private copy is changed here, which is threadsafe
}

void function()
{
    vec.push_back(var); // the global variable is changed here, which is not threadsafe
    return;
}

If you wish to use the private copy of your variable in a function you have to pass it as a reference to your function :

void function(std::vector<double>& x, double y)
{
    x.push_back(y);
    return;
}
...
#pragma omp for firstprivate(vec)
   for (int i = 0; i < 4; i++)
   {        
       function(vec, 1); 

   }

Note that, however, as pointed out and explained by @JeromeRichard you should not use global variables in your code.

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.