在 OpenMP 中共享作用域变量
Share scoped variable in OpenMP
我正在使用 OpenMP 并希望在线程之间共享在作用域块内声明的变量。这是我正在做的事情的总体思路:
#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());
}
}
}
按原样编译时,pixels
和 pitch
将是线程私有的并且仅在主线程中设置,从而导致段错误。有没有办法共享这些变量而不增加它们的范围(在 #pragma omp parallel
之前声明它们)或不必要地加入和重新创建线程(离开并行部分并进入另一个 #pragma omp parallel
块)?
解决此问题的一种方法是使用 OpenMP 任务。这是一个例子:
#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
}
此 task-based 实施受益于 较少的同步 (在 many-core 系统上成本高)。
另一种可能的替代方法是使用指针将私有变量的值共享给其他线程。但是,这种方法需要在并行部分之外声明一些共享变量,这在您的情况下可能是不可能的。
我正在使用 OpenMP 并希望在线程之间共享在作用域块内声明的变量。这是我正在做的事情的总体思路:
#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());
}
}
}
按原样编译时,pixels
和 pitch
将是线程私有的并且仅在主线程中设置,从而导致段错误。有没有办法共享这些变量而不增加它们的范围(在 #pragma omp parallel
之前声明它们)或不必要地加入和重新创建线程(离开并行部分并进入另一个 #pragma omp parallel
块)?
解决此问题的一种方法是使用 OpenMP 任务。这是一个例子:
#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
}
此 task-based 实施受益于 较少的同步 (在 many-core 系统上成本高)。
另一种可能的替代方法是使用指针将私有变量的值共享给其他线程。但是,这种方法需要在并行部分之外声明一些共享变量,这在您的情况下可能是不可能的。