c++ - OpenMP:如何在 PARALLEL block 中正确嵌套 MASTER 和 FOR?

标签 c++ c multithreading openmp openmpi

我正在开发一个同时使用 OpenMP 和 OpenMPI 的程序。

对于在初始节点上运行的进程,我希望有一个线程作为调度程序(与其他节点交互)和其他线程进行计算。

代码结构如下:

int computation(...)
{
    #pragma parallel for .....
}

int main(...)
{
    ...
    if (mpi_rank == 0) // initial node
    {
        #pragma omp parallel
        {
            #pragma omp master
            {
                // task scheduling for other nodes
            }
            {
                // WRONG: said 4 threads in total, this block will be executed for
                // 3 times simultaneously, and the nested "for" in the function
                // will spawn 4 threads each as well
                // so ACTUALLY 3*4+1=13 threads here!
                int computation(...);
            }
        }
    }
    else // other nodes
    {
        // get a task from node 0 scheduler by MPI
        int computation(...);
    }
}

我想要的是,在初始节点,调度器占用一个线程,同时只执行一个计算函数,所以最多同时使用4个线程。

我也试过:

int computation(...)
{
    register int thread_use = omp_get_max_threads();    // this is 4
    if (rank == 0)
    {
        --thread_use;   // if initial node, use 3
    }
    #pragma parallel for ..... num_threads(thread_use)
}

int main(...)
{
    ...
    if (mpi_rank == 0) // initial node
    {
        #pragma omp parallel
        {
            #pragma omp master
            {
                // task scheduling for other nodes
            }
            #pragma omp single
            {
                // WRONG: nest "for" can only use 1 thread
                int computation(...);
            }
        }
    }
    else // other nodes
    {
        // get a task from node 0 scheduler by MPI
        int computation(...);
    }
}

...或者

//other parts are the same as above
if (mpi_rank == 0) // initial node
{
    #pragma omp parallel num_threads(2)
    {
        #pragma omp master
        {
            // task scheduling for other nodes
        }
        {
            // WRONG: nest "for" can only use 1 thread
            int computation(...);
        }
    }
}

...但它们都不起作用。

我应该如何使用 OpenMP 安排 block 来实现我的目标?非常感谢任何帮助。

最佳答案

首先,如果要在OpenMP中指定嵌套并行,需要将环境变量OMP_NESTED设置为true

然后,可能的实现如下所示:

// Parallel region. Topmost level
#pragma omp parallel sections num_threads(2)
{
    #pragma omp section
    scheduling_function();

    #pragma omp section
    compute_function();
}

其中scheduling_function()是单线程函数,compute_function()结构类似于:

void compute_function() {
    // Nested parallel region. Bottommost level
    #pragma omp parallel
    {
        computation();
    }
}

有关 OpenMP nested parallelism 的更多信息

关于c++ - OpenMP:如何在 PARALLEL block 中正确嵌套 MASTER 和 FOR?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39838524/

相关文章:

架构 x86_64 : "function_name" referenced from 的 c++ undefined symbol

c++ - DLLNotFoundException异常

c++ - 指针和动态分配的数组

c++ - 为什么 Visual Studio 不将无符号值显示为 int?

Android:使用线程在指定时间做某事

c++ - std::condition_variable::wait_for 和 std::condition_variable::wait_until 有什么区别?

c++ - SSE 复制、AVX 复制和 std::copy 性能

c - 如何在c中将位设置为表格

c++ - 如果试图关闭一个已经关闭的套接字 winsock 会发生什么?

java - 在库中实现同步和异步方法的正确方法是什么?