Reputation: 1543
I'm working with OpenMP and would like to share variable that's declared inside scoped block between threads. Here's overall idea of what I'm doing:
#pragma omp parallel
{
// ...parallel code...
{
uint8_t* pixels;
int pitch;
#pragma omp barrier
#pragma omp master
{
// SDL video code must be run in main thread
SDL_LockTexture(renderTexture.get(), nullptr, (void**)&pixels, &pitch);
}
#pragma omp barrier
// parallel code that reads `pixels` and `pitch` and writes to texture
#pragma omp barrier
#pragma omp master
{
// Once done, main thread must do SDL call again (this will upload texture to GPU)
SDL_UnlockTexture(renderTexture.get());
}
}
}
When compiled as is, pixels
and pitch
will be thread-private and set only in main thread, leading to segfault. Is there a way to share those variables without increasing their scope (declaring them before #pragma omp parallel
) or needlessly joining and re-creating threads (leaving parallelized part and entering another #pragma omp parallel
block)?
Upvotes: 0
Views: 969
Reputation: 50278
One way to overcome this problem is to use OpenMP tasks. Here is an example:
#pragma omp parallel
{
// ...parallel code...
// May not be needed
#pragma omp barrier
#pragma omp master
{
uint8_t* pixels;
int pitch;
// SDL video code must be run in main thread
SDL_LockTexture(renderTexture.get(), nullptr, (void**)&pixels, &pitch);
// Note that the variables are firstprivate by default for taskloops
// and that shared variables must be explicitly listed as shared here
// (as opposed to an omp for).
#pragma omp taskloop collapse(2) firstprivate(pixels, pitch)
for(int y=0 ; y<height ; ++y)
{
for(int x=0 ; x<width ; ++x)
{
// Code reading `pixels` and `pitch` and writing into texture
}
}
// Once done, main thread must do SDL call again (this will upload texture to GPU)
SDL_UnlockTexture(renderTexture.get());
}
// May not be needed
#pragma omp barrier
}
This task-based implementation benefits from having less synchronizations (costly on many-core systems).
Another possible alternative is to use pointers to share the value of the private variable to other threads. However, this approach require some shared variables to be declared outside the parallel section which may not be possible in your case.
Upvotes: 1