OpenMP任务依赖性是否被忽略?

时间:2019-03-04 20:16:12

标签: c++ task openmp

首先,这是示例代码:

#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的含义吗?

1 个答案:

答案 0 :(得分:4)

该实现正在做正确的事情。

除了通过depend子句建立的顺序之外,任务创建在源代码中的位置还对依赖项产生影响。

在您的示例中,第一个任务对in变量具有x依赖性。由于队列中不存在对同一变量具有outinout依赖性的任务,因此该任务已准备就绪,可以立即执行,即使在遇到第二个任务之前,实现也可能会立即执行。

如果我交换了两个任务:

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依赖项。