当终止条件取决于来自不同部分的更新时,为什么 OMP 并行部分中的 while 循环无法终止

2021-12-26 00:00:00 while-loop for-loop openmp c++

下面的 C++ 代码是否合法,还是我的编译器有问题?代码使用

编译成共享库

gcc 版本 4.4.6 20110731 (Red Hat 4.4.6-3) (GCC)

和 openMP,然后通过 R 2.15.2 调用.

int it=0;#pragma omp 并行部分共享(它){#pragma omp 部分{std::cout<<进入A部分"<

我获得了以下输出(对 2 个线程的交织输出表示歉意,但我认为它是可以解释的):

进入A区迭代 以 it=0 进入 B 部分0迭代 1迭代 2迭代 3迭代 4迭代 5迭代 6迭代 7迭代 8迭代 9离开 A 部分=10

然后程序停止:B 部分似乎卡在了 while 循环中.由于变量it"是共享的,我不明白为什么当 A 部分完成时,while 循环不会终止.

解决方案

那是因为shared变量只是意味着它对所有线程都一样,但程序员仍然需要手动同步访问

共享条款

<块引用>

程序员有责任确保多个线程正确访问 SHARED 变量(例如通过 CRITICAL 部分)

因此,例如,您可以在第一部分完成后flush 变量:

 #pragma omp 部分{std::cout<<进入A部分"<

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.

解决方案

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;
      }

相关文章