C++ 带有 break 语句的并行 OpenMP 循环
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9793791/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Parallel OpenMP loop with break statement
提问by Jeanno
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. Basically I have 'for' loop, that loops through the elements of a large vector looking for one element that satisfies a certain condition. 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
我知道你不能有一个 OpenMP 循环的 break 语句,但我想知道是否有任何解决方法,同时仍然可以从并行性中受益。基本上我有'for'循环,它遍历一个大向量的元素,寻找一个满足特定条件的元素。但是,只有一个元素满足条件,因此一旦找到,我们就可以跳出循环,提前致谢
for(int i = 0; i <= 100000; ++i)
{
if(element[i] ...)
{
....
break;
}
}
采纳答案by Haatschii
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. Otherwise, 3 threads may be already finished while one still has halfway to got...
通过这种方式,您必须在每个循环中测试“go”,但这应该无关紧要。更重要的是,这将对应于“静态” omp for 循环,只有当您期望所有迭代都花费相似的时间时,这才有用。否则,3个线程可能已经完成,而一个还有一半的时间......
回答by yyfn
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。
回答by enobayram
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;
}
}
}
回答by Peter Smartt
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;
}
}
}
回答by Z boson
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;
}
}
}