0

我有一个 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;
        }
    }

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

4

6 回答 6

2

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

于 2013-10-14T08:54:51.077 回答
2

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

于 2013-10-14T10:08:23.423 回答
2

我将在这里尝试以更明确的方式重新表述@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

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

于 2013-10-15T19:28:57.170 回答
1

用这个

 #pragma omp parallel for

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

于 2013-10-14T09:32:13.840 回答
1

我认为您可以通过使用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.
    }

}

这可能会导致性能开销。

于 2013-10-14T11:10:38.970 回答
0

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

于 2013-10-14T17:27:19.840 回答