带部分的 OpenMP 嵌套并行性
OpenMP nested parallelism with sections
我遇到以下情况:我有一个很大的外部 for 循环,它基本上包含一个函数 foo()。 foo()内部有bar1()和bar2()可以并发执行,bar3()需要在bar1()和bar2()执行完之后执行。我已经并行化了大外循环以及 bar1() 和 bar2() 部分。我假设每个外循环线程都会生成自己的部分线程,这是正确的吗?
如果上面的假设是正确的,如何让 bar3() 仅在执行 bar1() 和 bar2() 的线程完成后才执行?如果我使用 critical,它将在所有线程上停止,包括外部 for 循环。如果我使用 single,则无法保证 bar1() 和 bar2() 会完成。
如果上述假设不正确,如何强制外循环线程重新使用 bar1()、bar2() 的线程而不是每次都生成新线程?
请注意,temp 是一个变量,它的 init 和 clear 开销很大,所以我将 init 和 clear 拉到 for 循环之外。它使事情更加复杂,因为 bar1() 和 bar2() 都需要某种临时变量。最佳情况下,应该为创建的每个线程初始化和清除 temp,但我不确定如何为为部分生成的线程强制执行此操作。 (没有 sections 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);
}
我相信简单地并行化 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);
}
我遇到以下情况:我有一个很大的外部 for 循环,它基本上包含一个函数 foo()。 foo()内部有bar1()和bar2()可以并发执行,bar3()需要在bar1()和bar2()执行完之后执行。我已经并行化了大外循环以及 bar1() 和 bar2() 部分。我假设每个外循环线程都会生成自己的部分线程,这是正确的吗?
如果上面的假设是正确的,如何让 bar3() 仅在执行 bar1() 和 bar2() 的线程完成后才执行?如果我使用 critical,它将在所有线程上停止,包括外部 for 循环。如果我使用 single,则无法保证 bar1() 和 bar2() 会完成。
如果上述假设不正确,如何强制外循环线程重新使用 bar1()、bar2() 的线程而不是每次都生成新线程?
请注意,temp 是一个变量,它的 init 和 clear 开销很大,所以我将 init 和 clear 拉到 for 循环之外。它使事情更加复杂,因为 bar1() 和 bar2() 都需要某种临时变量。最佳情况下,应该为创建的每个线程初始化和清除 temp,但我不确定如何为为部分生成的线程强制执行此操作。 (没有 sections 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);
}
我相信简单地并行化 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);
}