首先,这是示例代码:
#include <iostream>
int main()
{
int x = 100;
#pragma omp parallel
{
#pragma omp single
{
#pragma omp task depend (in: x)
{ x += 1; }
#pragma omp task depend (out: x)
{ x *= 2; }
}
}
printf("x = %d\n", x); // prints 202
}
据我了解,task depend(in: x)
应该与depend(out: x)
等待一切,但这似乎并不是正在发生的事情。
在这种情况下,输出为202
,表明x
先递增,然后再增加一倍。
事实上,我已经尝试了in / out和out / in,以及切换了任务本身的定义顺序。无论输入/输出依赖性如何,任务始终从上到下执行。
我误解了task depend
的含义吗?
答案 0 :(得分:4)
该实现正在做正确的事情。
除了通过depend
子句建立的顺序之外,任务创建在源代码中的位置还对依赖项产生影响。
在您的示例中,第一个任务对in
变量具有x
依赖性。由于队列中不存在对同一变量具有out
或inout
依赖性的任务,因此该任务已准备就绪,可以立即执行,即使在遇到第二个任务之前,实现也可能会立即执行。
如果我交换了两个任务:
int main()
{
int x = 100;
#pragma omp parallel
{
#pragma omp single
{
#pragma omp task depend (out: x)
{ x *= 2; }
#pragma omp task depend (in: x)
{ x += 1; }
}
}
printf("x = %d\n", x); // prints 201
}
代码按预期打印201。我使用Intel Compiler 18.0.3对此进行了测试。
正确的代码依赖关系建模看起来像这样:
int main()
{
int x = 100;
#pragma omp parallel
{
#pragma omp single
{
#pragma omp task depend (inout: x)
{ x *= 2; }
#pragma omp task depend (inout: x)
{ x += 1; }
}
}
printf("x = %d\n", x); // prints 201
}
代码仍然显示202,但是现在相关性正确地模拟了x
的实际用法:任务1读取了x
的旧值并对其进行了修改,因此它应该使用{{1} }依赖。任务2还读取inout
并对其进行修改,因此它也应使用x
依赖项。