简体   繁体   English

带有break语句的并行OpenMP循环

[英]Parallel OpenMP loop with break statement

I know that you cannot have a break statement for an OpenMP loop, but I was wondering if there is any workaround while still the benefiting from parallelism. 我知道你不能有一个OpenMP循环的break语句,但我想知道是否有任何解决方法,同时仍然受益于并行性。 Basically I have 'for' loop, that loops through the elements of a large vector looking for one element that satisfies a certain condition. 基本上我有'for'循环,循环遍历大向量的元素,寻找满足某个条件的一个元素。 However there is only one element that will satisfy the condition so once that is found we can break out of the loop, Thanks in advance 但是只有一个元素可以满足条件,所以一旦发现我们可以突破循环,提前谢谢

for(int i = 0; i <= 100000; ++i)
  {
    if(element[i] ...)
     {
          ....
          break;
      }
   }

See this snippet: 看到这个片段:

volatile bool flag=false;

#pragma omp parallel for shared(flag)
for(int i=0; i<=100000; ++i)
{    
    if(flag) continue;
    if(element[i] ...)
    {
          ...
          flag=true;
    }
}

This situation is more suitable for pthread. 这种情况更适合pthread。

You could try to manually do what the openmp for loop does, using a while loop: 您可以尝试使用while循环手动执行openmp for循环:

const int N = 100000;
std::atomic<bool> go(true);
uint give = 0;

#pragma omp parallel
{
    uint i, stop;

    #pragma omp critical
    {
        i = give;
        give += N/omp_get_num_threads();
        stop = give;

        if(omp_get_thread_num() == omp_get_num_threads()-1)
            stop = N;
    } 


    while(i < stop && go)
    {
        ...
        if(element[i]...)
        {
            go = false;
        }
        i++;
    }
}

This way you have to test "go" each cycle, but that should not matter that much. 这样你就必须在每个周期测试“走”,但这不应该那么重要。 More important is that this would correspond to a "static" omp for loop, which is only useful if you can expect all iterations to take a similar amount of time. 更重要的是,这将对应于循环的“静态”omp,这仅在您可以预期所有迭代花费相似的时间量时才有用。 Otherwise, 3 threads may be already finished while one still has halfway to got... 否则,3个线程可能已经完成,而其中一个仍然有一半...

I would probably do (copied a bit from yyfn) 我可能会做(从yyfn复制一下)

volatile bool flag=false;

for(int j=0; j<=100 && !flag; ++j) {
  int base = 1000*j;
  #pragma omp parallel for shared(flag)
  for(int i = 0; i <= 1000; ++i)
  {

    if(flag) continue;
    if(element[i+base] ...)
     {
          ....
          flag=true;
      }
   }
}
bool foundCondition = false;
#pragma omp parallel for
for(int i = 0; i <= 100000; i++)
{
    // We can't break out of a parallel for loop, so this is the next best thing.
    if (foundCondition == false && satisfiesComplicatedCondition(element[i]))
    {
        // This is definitely needed if more than one element could satisfy the
        // condition and you are looking for the first one.  Probably still a
        // good idea even if there can only be one.
        #pragma omp critical
        {
            // do something, store element[i], or whatever you need to do here
                ....

            foundCondition = true;
        }
    }
}

Here is a simpler version of the accepted answer. 这是一个更简单的接受答案的版本。

int ielement = -1;
#pragma omp parallel
{
    int i = omp_get_thread_num()*n/omp_get_num_threads();
    int stop = (omp_get_thread_num()+1)*n/omp_get_num_threads();        
    for(;i <stop && ielement<0; ++i){
        if(element[i]) {
            ielement = i;
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM