在 OpenMP 线程之间进行通信

Communicating between OpenMP threads

本文关键字:通信 之间 OpenMP 线程      更新时间:2023-10-16

我有一个 OpenMP 循环,我希望在任何其他线程继续之前完成第一次迭代。我尝试使用全局变量,初始化为"false",当第一次迭代完成时将其设置为"true",但这似乎没有按预期工作(我陷入了无限循环)。

例如:

    bool FirstDone = false; // This is a global variable
    ...
    #pragma omp parallel for
    for(int i=0;i<max;i++)
    {
        while(!FirstDone && i>0){}
        if(i==0)
        {
            // Do something
            FirstDone = true;
        }
    }

谁能阐明为什么这不起作用?

循环外进行第一次迭代,从 i=1 开始,如果你想继续你的逻辑,将 FirstDone 更改为可变性,但它仍然不起作用,因为不能保证线程排序

>您可以将第一次迭代包装在 OpenMP single 结构中。这将确保遇到构造的第一个线程将执行它,并且所有其他线程将等到它完成,然后再继续其余的计算。

我将在这里尝试以更明确的方式改写@HighPerformanceMark的答案(即使用一些代码草图来支持语句)。只是为了修复想法,假设循环的串行版本如下所示:

for(int ii = 0; ii < max; ii++)
{   
    // Do a lot of work based on ii
    if(ii==0)
    {
        //////////////////////////////////////////////////
        // Do something special for the first iteration //
        //////////////////////////////////////////////////
    }
}

在之前的回答中简要提出的是用这个简单的逻辑并行化它

// Move the loop body into a function
void loopIteration(const size_t ii) {
    // Do a lot of work based on ii
}
#pragma omp parallel
{
// Single directive: the first one enters, the other wait at the implicit barrier
#pragma omp single
    {
        loopIteration(0);
        //////////////////////////////////////////////////
        // Do something special for the first iteration //
        //////////////////////////////////////////////////
    } // single: implicit barrier
// Loop work-sharing construct on the remaining iterations
#pragma omp for
    for(int ii = 1; ii < max; ii++)
    {   
       loopIteration(ii);         
    } // for: implicit barrier
} // parallel

主要思想是将循环体移动到函数中以避免代码重复,并从循环中显式展开第一次迭代。

使用这个

 #pragma omp parallel for

默认情况下,它从第一次迭代开始。

我认为您可以通过使用 ordered 子句和区域来实现这一点,例如。

#pragma omp parallel for ordered
for(int i=0;i<max;i++)
{
    #pragma omp ordered
    if (i == 0)
    {
        // Do stuff in the first iteration, others wait.
    }
}

这可能会产生性能开销。

您是否尝试过简单地删除.empty while循环并在if语句后设置障碍?