Implicit barrier at the end of #pragma for

Friends, I'm trying to learn the openMP paradigm. I used the following code to understand #omp for pragma.

int main(void){ int tid; int i; omp_set_num_threads(5); #pragma omp parallel \ private(tid) { tid=omp_get_thread_num(); printf("tid=%d started ...\n", tid); fflush(stdout); #pragma omp for for(i=1; i<=20; i++){ printf("t%d - i%d \n", omp_get_thread_num(), i); fflush(stdout); } printf("tid=%d work done ...\n", tid); } return 0; 

}

In the above code, there is an implicit barrier at the end of #pragma omp parallel, that is, all threads 0,1,2,3,4 must reach it before moving on to the next statement.

So, to check this barrier, I included this "pragma for" in the condition if (tid! = 0), which means all threads except stream 0, i.e. 1,2,3,4 should complete their work in a loop and wait forever. But, to my surprise, this does not happen. Each thread performs its iteration and successfully exits. ie t1 completes the iteration 5,6,7,8 ---- t2 makes 9,10,11,12 ---- t3 is 13,14,15,16, and t4 is 17,18,19,20. Note: iteration 1,2,3,4 never completed.

To dig deeper, instead of tid! = 0, I put the same #pragma for in tid! = 1, and instead of thread0, thread1 bypasses the barrier. To my surprise, the program now freezes and all threads are waiting for thread1.

Can someone please explain this unexpected behavior to me. The final code that is hung:

 int main(void){ int tid; int i; omp_set_num_threads(5); #pragma omp parallel \ private(tid) { tid=omp_get_thread_num(); printf("tid=%d started ...\n", tid); fflush(stdout); if(tid!=1){ /* worksharing */ #pragma omp for for(i=1; i<=20; i++){ printf("t%d - i%d \n", omp_get_thread_num(), i); fflush(stdout); } }else{ printf("t1 reached here. \n"); } printf("tid=%d work done ...\n", tid); } return 0; 

}

I tried to configure public or private, but it did not change the behavior of the program.

+4
source share
1 answer

The problem here is that the behavior is undefined by standard. From section 2.5, line 21 of the OpenMP 3.1 specification (but the text remained the same more or less from the very beginning):

β€’ Each area of ​​work exchange should be met by all flows in a team or none at all.

Where omp for is a bypass construct. So yes, I, as a rule, also expect you to hang your code, but the compiler has the right to assume that what you do never happens, and therefore the end result - it sometimes freezes, but sometimes not, depending from the details on which threads you are holding back - maybe this is not surprising.

+5
source

Source: https://habr.com/ru/post/1392837/


All Articles