【问题标题】:OpenMP Task Dependency Ignored?忽略 OpenMP 任务依赖性?
【发布时间】:2019-03-04 20:16:11
【问题描述】:

首先,这是示例代码:

#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的意思?

【问题讨论】:

    标签: c++ task openmp


    【解决方案1】:

    实现是正确的。

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

    在您的示例中,第一个任务具有对 x 变量的 in 依赖项。由于队列中没有现有任务对同一变量具有 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 的旧值并修改它,因此它应该使用 inout 依赖关系。任务 2 还读取 x 并对其进行修改,因此它也应该使用 inout 依赖。

    【讨论】:

    • 您的两个 sn-ps 是相同的,您可能需要更新 // prints 评论。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-09-01
    • 2015-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-06
    • 1970-01-01
    相关资源
    最近更新 更多