Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
210 views
in Technique[技术] by (71.8m points)

c++ - Task Dependency in OpenMP 4

The following code works based on the OpenMP 4.0 specification:

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.

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?

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;
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Question 1 : This means that task3 becomes dependent of task2. Right?

According to the OpenMP 4.0 standard on the depend clause (emphasis mine):

Task dependences are derived from the dependence-type of a depend clause and its list items, where dependence-type is one of the following:

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.

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.

From this description follows that:

  • the clause depend(in:x) will generate a task dependent on all the previously generated tasks with depend(out:x) or depend(inout:x)
  • the clause depend(out:x) or the clause depend(inoout:x) will generate a task dependent on all the previously generated tasks mentioning x in a depend 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)   

Therefore task3 depends on the completion of task2.


Question 2 : Why should an input-output dependency task be a dependent of an input dependency task?

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).


Question 3 : What do I need to do in order to make them independent?

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 and y == 2
  • x == 2 and y == 3

depending on whether task2 executes before task3 or not.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...