在 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());
        }
    }
}

按原样编译时,pixelspitch 将是线程私有的并且仅在主线程中设置,从而导致段错误。有没有办法共享这些变量而不增加它们的范围(在 #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 系统上成本高)。

另一种可能的替代方法是使用指针将私有变量的值共享给其他线程。但是,这种方法需要在并行部分之外声明一些共享变量,这在您的情况下可能是不可能的。