以下代码基于OpenMP 4.0规范工作:
out和 inout 依赖类型。生成的任务将是一个 所有先前生成的兄弟任务的依赖任务 引用in,out或inout中的至少一个列表项 依赖型列表。
这意味着task3变得依赖于task2。对?但它没有意义!为什么输入 - 输出依赖性任务应该是输入依赖性任务的依赖?
为了使它们独立,我需要做什么? p.s:在Linux上用g ++ 4.9测试的代码。
#include <stdio.h>
#include <omp.h>
#include <unistd.h>
int main() {
int x,y;
#pragma omp parallel num_threads(10)
{
#pragma omp single nowait
{
#pragma omp task depend (out:x) //task1
{
x=1;
}
#pragma omp task depend(in:x) depend(out:y) //task2
{
sleep(2); //Does task3 wait for us? Yes!
y=x+1;
}
#pragma omp task depend (inout:x) //task3
{
x++;
printf("task3(x): %d\n" , x);
}
#pragma omp task depend (in:x,y) //task4
{
printf("task4 (x+y): %d\n" , x+y);
}
}
}
return 0;
}
答案 0 :(得分:13)
问题1 :这意味着task3变得依赖于task2。对吗?的
根据depend
条款的OpenMP 4.0标准(强调我的):
任务依赖性来自
depend
的依赖类型 子句及其列表项,其中依赖类型是其中之一 以下内容:in 依赖类型。生成的任务将是依赖 所有先前生成的兄弟任务的任务 out或inout依赖类型中的至少一个列表项 列表强>
out和inout 依赖类型。生成的任务将是一个 依赖任务所有以前生成的兄弟任务,它们至少引用一个列表项 in,out或inout依赖类型列表。
从以下描述:
depend(in:x)
将根据depend(out:x)
或depend(inout:x)
depend(out:x)
或条款depend(inoout:x)
将生成一个任务,该任务取决于x
条款中提及depend
的所有先前生成的任务将此应用于您的特定情况会产生一系列此类依赖关系:
task1 (out:x) -> task2 (in:x,out:y) -> task4 (in:x,y)
| ^
| |
> task3 (inout:x)
因此 task3取决于task2的完成情况。
问题2 :为什么输入输出依赖项任务必须依赖于输入依赖项任务?
我只是让你注意到,通过这条规则,你将在运行结束时获得变量x
和y
的确定性值(假设你负责同步对内存的访问) 。如果task3依赖于task1而不是task2,则此确定性将不会成立(并且inout
依赖性将等同于in
依赖项。)
问题3 :为了让它们独立,我需要做些什么?
将inout:x
依赖项转换为in:x
依赖项,并通过x
子句同步对atomic
的访问。这样你就可以运行:
x == 2
和y == 2
x == 2
和y == 3
取决于task2是否在task3之前执行。