Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does while loop in an OMP parallel section fail to terminate when termination condition depends on update from different section

Is the C++ code below legal, or is there a problem with my compiler? The code was complied into a shared library using

gcc version 4.4.6 20110731 (Red Hat 4.4.6-3) (GCC)

and openMP and then called via R 2.15.2.

int it=0;
#pragma omp parallel sections shared(it)
   {
      #pragma omp section
      {
           std::cout<<"Entering section A"<<std::endl;
           for(it=0;it<10;it++)
           {
                   std::cout<<"Iteration "<<it<<std::endl;

           }
           std::cout<<"Leaving section A with it="<<it<<std::endl;
      }

      #pragma omp section
      {
           std::cout<<"Entering section B with it="<<it<<std::endl;
           while(it<10)
           {
                   1;
           }
           std::cout<<"Leaving section B"<<std::endl;
  }
}

I obtain the following output (apologies for interweaving output from 2 threads but I think it is interpretable):

Entering section A
Iteration Entering section B with it=0
0
Iteration 1
Iteration 2
Iteration 3
Iteration 4
Iteration 5
Iteration 6
Iteration 7
Iteration 8
Iteration 9
Leaving section A with it=10

The program then stalls: section B seems to get stuck in the while loop. Since the variable 'it' is shared I do not understand why the while loop doesn't terminate when section A is complete.

like image 576
wjastle Avatar asked Apr 30 '13 17:04

wjastle


1 Answers

That is because shared variable only means it it the same for all threads, but programmer still has to synchronize access by hands

SHARED Clause

It is the programmer's responsibility to ensure that multiple threads properly access SHARED variables (such as via CRITICAL sections)

So, you can, for example, flush variables after first section is completed:

      #pragma omp section
      {
           std::cout<<"Entering section A"<<std::endl;
           for(it=0;it<10;it++)
           {
                   std::cout<<"Iteration "<<it<<std::endl;

           }
           #pragma omp flush(it)
           std::cout<<"Leaving section A with it="<<it<<std::endl;
      }

      #pragma omp section
      {
           std::cout<<"Entering section B with it="<<it<<std::endl;
           while(it<10)
           {
            #pragma omp flush(it)
                   1;
           }
           std::cout<<"Leaving section B"<<std::endl;
      }
like image 128
Lol4t0 Avatar answered Oct 01 '22 14:10

Lol4t0