Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing a thread's private memory in OpenMP

According to the OpenMP Memory Model, the following is incorrect:

int *p0 = NULL, *p1 = NULL;
#pragma omp parallel shared(p0,p1)
{
  int x;
  // THREAD 0              // THREAD 1
  p0 = &x;                 p1 = &x;
  *p1 ...                  *p0 ...
}

My example looks like the following though:

int *p0 = NULL, *p1 = NULL;
#pragma omp parallel shared(p0,p1)
{
  int x;
  // THREAD 0              // THREAD 1
  p0 = &x;                 p1 = &x;
  #pragma omp flush

  #pragma omp barrier
  *p1 ...                  *p0 ...
  #pragma omp barrier
}

Would this be incorrect? I cannot find something in the memory model that would disallow this.

I assume that my toy example is correct, as in the memory model in 3.1 they allow a task to have access to a private variable as long as the programmer ensures that it is still alive. Given the fact that tasks can be untied, they can in theory execute within a different worker thread, therefore allowing an OpenMP thread access to the private memory of another.

like image 379
ipapadop Avatar asked Nov 17 '11 02:11

ipapadop


2 Answers

This should work. Flush syncs all shared variables and barrier guarantees that the mp environment with all threads is still active. As long as you don't use p0 in p1s assignment or vice versa it should be fine. Although I cannot imagine why one would do something like that. Maybe you can tell more about the reasoning behind that construct.

Since p0 and p1 are still alive after the parallel region, you could do all assignments there as well without barriers etc..

like image 157
Bort Avatar answered Oct 17 '22 04:10

Bort


As a side thought, this is analogous to trying to read a local variable inside some function you've called by assigning that local variable to a global variable, then reading the global variable.

The analogy here is that a global variable acts like a shared variable in multithreading, essentially giving access to what was supposed to be thread private (like the local variable that should only be visible within the function).

So to answer the question as asked, doing dereferencing into thread private memory is completely valid. It is allowed because pointer aliasing is allowed (this is where 2 or more variables provide access to the same location in memory, in your case one is a thread private integer and the other is a shared pointer).

Although completely valid, beware this can cause some difficult to detect race conditions, as typically one would not use a lock to protect access to thread private variables.

like image 37
Jason Avatar answered Oct 17 '22 05:10

Jason