OpenMP 4 中的任务依赖性
以下代码基于 OpenMP 4.0 规范工作:
The following code works based on the OpenMP 4.0 specification:
out 和 inout 依赖类型.生成的任务将是所有先前生成的同级任务的依赖任务在 in、out 或 inout 中引用至少一个列表项依赖类型列表.
The out and inout dependence-types. The generated task will be a dependent task of all previously generated sibling tasks that reference at least one of the list items in an in, out, or inout dependence-type list.
这意味着 task3 变得依赖于 task2.对?但这没有意义!为什么输入-输出依赖任务应该依赖于输入依赖任务?
This means that task3 becomes dependent of task2. Right? but it does not make sense! Why should an input-output dependency task be a dependent of an input dependency task?
我需要做什么才能让他们独立?ps:在 Linux 上使用 g++ 4.9 测试的代码.
What do I need to do in order to make them independent? p.s: code tested with g++ 4.9 on Linux.
#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
" , x);
}
#pragma omp task depend (in:x,y) //task4
{
printf("task4 (x+y): %d
" , x+y);
}
}
}
return 0;
}
推荐答案
问题 1 : 这意味着 task3 变得依赖于 task2.对吧?
根据depend
子句(强调我的):
According to the OpenMP 4.0 standard on the depend
clause (emphasis mine):
任务依赖来自 depend
的依赖类型子句及其列表项,其中依赖类型是以下:
Task dependences are derived from the dependence-type of a
depend
clause and its list items, where dependence-type is one of the following:
in 依赖类型.生成的任务将是一个依赖的 所有先前生成的同级任务的任务,这些任务在out 或 inout 依赖类型中的至少一个列表项列表.
The in dependence-type. The generated task will be a dependent task of all previously generated sibling tasks that reference at least one of the list items in an out or inout dependence-type list.
out 和 inout 依赖类型.生成的任务将是依赖任务之前生成的所有同级任务,这些任务至少引用了一个列表项中的一个in、out 或 inout 依赖类型列表.
The out and inout dependence-types. The generated task will be a dependent task of all previously generated sibling tasks that reference at least one of the list items in an in, out, or inout dependence-type list.
从这个描述可以看出:
- 子句
depend(in:x)
将生成一个依赖于所有先前生成的任务的任务depend(out:x)
或depend(inout:x)
- 子句
depend(out:x)
或子句depend(inoout:x)
将生成一个依赖于所有先前生成的提及x 的任务的任务
在depend
子句中
- the clause
depend(in:x)
will generate a task dependent on all the previously generated tasks withdepend(out:x)
ordepend(inout:x)
- the clause
depend(out:x)
or the clausedepend(inoout:x)
will generate a task dependent on all the previously generated tasks mentioningx
in adepend
clause
将此应用到您的特定情况会产生这种依赖链:
Applying this to your specific case gives a chain of dependencies of this kind:
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
依赖项.
I would just let you notice that with this rule you will have a deterministic value of your variables x
and y
at the end of the run (assuming you take care of synchronizing accesses to memory). If task3 was dependent on task1 instead of task2, this determinism wouldn't hold (and an inout
dependency would have been equivalent to an in
dependency).
问题 3:我需要做什么才能让他们独立?
将inout:x
依赖转化为in:x
依赖,通过atomic
同步访问x
条款.这样你就可以运行:
Turn the inout:x
dependency into an in:x
dependency and synchronize accesses to x
via atomic
clauses. That way you will have runs in which either:
x == 2
和y == 2
x == 2
和y == 3
x == 2
andy == 2
x == 2
andy == 3
取决于task2是否在task3之前执行.
depending on whether task2 executes before task3 or not.
相关文章