Class declaring itself (*this) private to avoid race conditions / quest for threadprivate in gcc abandoned
This is a long-standing missing GCC feature:
- OpenMP threadprivate directive does not work with non-POD types
With current GCC versions, thread_local
is expected to work, though:
int main() {
thread_local lotswork production(0);
production.carryout();
}
However, I do not think this will work in your case because the parallel loop in carryout
will still operate on a single lotswork
instance. I believe this would apply to the original code using threadprivate
, too. You probably need to move the parallel loop outside of the carryout
member function.
It seems like there is some confusion about OpenMP constructs here. threadprivate
is used, much like thread_local, to create a per-thread copy of an object of static lifetime, either a global or a static variable. As noted, there are some implementation issues with this, but even if the implementations could handle the class, using threadprivate
on a non-static local variable would produce an error.
As to the error, it's hard to say without output, but it is likely multiple things:
- The unmatched closing brace. Placing a
{
on the end of a pragma line does not open a block, it needs to be on the following line. - It is not valid to privatize an enclosing class instance that way
If you need to create a private copy of the enclosing class in each thread, it's possible by either copy-constructing the class into a variable declared inside a parallel region:
#pragma omp parallel
{
lotswork tmp(*this);
// do things with private version
}
Note however that the entire thing is private, so this means that f
in the original copy will not be updated unless you perform the addInt
equivalents all on the private copies then the f[n]
assignments on the original.
Edit: I originally mentioned using the default(firstprivate)
clause, but the
default clause only offers private and first private for FORTRAN. To get the
same effect in c++, do the above and copy construct into a new instance of each,
or use a lambda with capture by value by default then firstprivate that, *this
requires c++17 to work, but does exactly what's requested:
auto fn = [=,*this](){
// do things with private copies
// all updates to persist in shared state through pointers
};
#pragma omp parallel firstprivate(fn)
fn();