我知道在OpenMP循环中不能使用break语句,但我想知道是否有任何解决方法,同时仍然能够从并行性中受益。基本上,我有一个'for'循环,它循环遍历一个大向量的元素,寻找满足特定条件的一个元素。然而只有一个元素会满足条件,因此一旦找到该元素,我们就可以退出循环。提前谢谢。
for(int i = 0; i <= 100000; ++i)
{
if(element[i] ...)
{
....
break;
}
}
我知道在OpenMP循环中不能使用break语句,但我想知道是否有任何解决方法,同时仍然能够从并行性中受益。基本上,我有一个'for'循环,它循环遍历一个大向量的元素,寻找满足特定条件的一个元素。然而只有一个元素会满足条件,因此一旦找到该元素,我们就可以退出循环。提前谢谢。
for(int i = 0; i <= 100000; ++i)
{
if(element[i] ...)
{
....
break;
}
}
请看以下代码片段:
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;
}
}
这种情况更适合使用 pthread。
您可以尝试使用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++;
}
}
这样,您需要在每个周期测试“go”,但这并不那么重要。更重要的是,这将对应于一个“静态”的omp for循环,仅当您可以预期所有迭代花费类似的时间时才有用。否则,3个线程可能已经完成,而另一个线程仍然完成一半...
go
。此外,内存模型保证除非在两个原子操作中都添加了 seq_cst
,否则不会有可见性。 - Zulango
使用std::atomic<bool>
。我会相应地编辑答案。 - Haatschii我可能会做(从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;
}
}
}
这里是被接受答案的一个更简单的版本。
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;
}
}
}
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;
}
}
}
bool
与 false
进行比较是明智的吗? - Tomilov Anatoliy