Produce OpenMP code given dependency graph

时间:2016-02-12 21:39:17

标签: openmp dependency-graph

I have a question on how to produce OpenMP pseudocode when you have a specific dependency graph in mind. So suppose that we have this specific graph:

Dependence graph

A solution could be something like this:

[('loss', 100000.0), ('injury', 75000.0), ('fall', 150000.0), ('slip', 150000.0), ('fault', 50000.0)]

Now the thing is that although the code above does succeed important parallelism, task E has to wait for task D to complete and task F has to wait for task B to complete, which is not required according to the graph.

So my question is, can someone provide me with OpenMP pseudocode where E won't wait for D and F won't wait for B for the given dependency graph?

1 个答案:

答案 0 :(得分:4)

为此,OpenMP标准为depend指令提出task子句。

在您的具体情况下,我猜这可以像这样使用:

#include <stdio.h>

int a, b, c;

void A() {
    a = b = c = 1;
    printf( "[%d]In A: a=%d b=%d c=%d\n", omp_get_thread_num(), a, b, c );
}

void B() {
    a++;
    sleep( 3 );
    printf( "[%d]In B: a=%d\n", omp_get_thread_num(), a );
}

void C() {
    b++;
    sleep( 2 );
    printf( "[%d]In C: b=%d\n", omp_get_thread_num(), b );
}

void D() {
    c++;
    sleep( 1 );
    printf( "[%d]In D: c=%d\n", omp_get_thread_num(), c );
}

void E() {
    a++;
    sleep( 3 );
    printf( "[%d]In E: a=%d, b=%d\n", omp_get_thread_num(), a, b );
}

void F() {
    c++;
    sleep( 1 );
    printf( "[%d]In F: b=%d c=%d\n", omp_get_thread_num(), b, c );
}

int main() {

    #pragma omp parallel num_threads( 8 )
    {
        #pragma omp single
        {
           #pragma omp task depend( out: a, b, c )
           A();
           #pragma omp task depend( inout: a )
           B();
           #pragma omp task depend( inout: b )
           C();
           #pragma omp task depend( inout: c )
           D();
           #pragma omp task depend( inout: a ) depend( in: b )
           E();
           #pragma omp task depend( inout: c ) depend( in: b )
           F();
        }
    }
    printf( "Finally a=%d b=%d c=%d\n", a, b, c );

    return 0;
}

如您所见,我介绍了一些变量abc,我用它来定义任务之间的依赖关系。我也相应地在调用中修改它们,虽然这不是必需的(我只是为了显示如何处理流程)。

以下是我在机器上的内容:

~/tmp$ gcc -fopenmp depend.c
~/tmp$ ./a.out 
[6]In A: a=1 b=1 c=1
[7]In D: c=2
[2]In C: b=2
[6]In B: a=2
[2]In F: b=2 c=3
[6]In E: a=3, b=2
Finally a=3 b=2 c=3