我有以下情况:我有一个很大的外部for循环,基本上包含一个函数foo()。在foo()中,可以同时执行bar1()和bar2(),并且需要在bar1()和bar2()之后执行bar3()。我已经并行化了大外环,并且部分为bar1()和bar2()。我假设每个外部循环线程都会生成自己的节线程,这是正确的吗?
如果上面的假设是正确的,那么只有在执行bar1()和bar2()的线程完成后才能让bar3()执行?如果我使用critical,它将在所有线程上停止,包括外部for循环。如果我使用单曲,那么就不能保证bar1()和bar2()会完成。
如果上面的假设不正确,我如何强制外部循环线程重新使用bar1(),bar2()的线程,并且每次都不生成新线程?
请注意,temp是一个变量,其init和clear很昂贵,所以我在init循环外拉init并清除。它使问题更加复杂,因为bar1()和bar2()都需要某种临时变量。最理想的是,temp应该为每个创建的线程初始化和清除,但是我不确定如何强制为段生成的线程。 (没有section pragma,它在并行块中工作正常)。
main(){
#pragma omp parallel private(temp)
init(temp);
#pragma omp for schedule(static)
for (i=0;i<100000;i++) {
foo(temp);
}
clear(temp);
}
foo() {
init(x); init(y);
#pragma omp sections
{
{ bar1(x,temp); }
#pragma omp section
{ bar2(y,temp); }
}
bar3(x,y,temp);
}
答案 0 :(得分:1)
我认为简单地并行化for循环应该会给你足够的并行性来饱和CPU中的资源。但是如果你真的想并行运行两个函数,那么下面的代码就可以了。
main(){
#pragma omp parallel private(temp)
{
init(temp);
#pragma omp for schedule(static)
for (i=0;i<100000;i++) {
foo(temp);
}
clear(temp);
}
}
foo() {
init(x); init(y);
#pragma omp task
bar1(x,temp);
bar2(y,temp);
#pragma omp taskwait
bar3(x,y,temp);
}