OpenMP並列化(forループ内にberakがある場合)

forループの中にbreakがある場合OpenMPで並列化しようとしてもコンパイルエラーとなって並列化出来ない。


 #pragma omp parallel for
 for ( int i = 0; i < 1000; i++ )
 {
      .........
     if ( xxxx )
     {
        break;
     }
     ......
 }


以下のようにして(例えば)LoopInBreakクラスを使うことでbreakがforループにあっても並列化出来る。


int break_flag = false;
#pragma omp parallel
{
   LoopInBreak omp(並列化数, 1000, &break_flag );
   for ( int i = omp.Begin(); omp.Condition(i); i++ )
   {
       .........
       if ( xxxx )
       {
           MY_LOOP_BREAK(omp);
       }
       ......
   }
}


class Thread_omp_LoopInBreak
{
 int threadNum_;   //スレッド数設定
 int loopNum_;   //ループ数 ( 0...loopNum-1)
 int threadId;   //スレッドID
 
 //並列化されている今のタスクが行うべきループ処理の開始と終了値
 int i_st;
 int i_ed;
 
 int* break_flag_;
 
public:
 Thread_omp_LoopInBreak( int threadNum, int loopNum, int* break_flag):threadNum_(threadNum),loopNum_(loopNum),break_flag_(break_flag)
 {
#ifdef USE_OPENMP 
  threadNum_ = threadNum;
  loopNum_ = loopNum;
  //並列化されているときの今のタスクのスレッドID
  threadId = omp_get_thread_num();
  
  //並列化の分割ステップ
  int n = (loopNum_  + threadNum_ -1 )/threadNum_;
  //並列化されている今のタスクが行うべきループ処理の開始と終了値
  i_st = n*threadId;
  i_ed = ( i_st + n < loopNum_ ) ? i_st + n: loopNum_;
#else
  threadNum_ = 1;
  loopNum_ = loopNum;
  threadId = 0;
  i_st = 0;
  i_ed = loopNum_;
#endif
  //printf("threadNum(%d) loop %d ~ %d\n", threadId, i_st, i_ed );
 }
 
 inline int Id()
 {
  //並列化されているときの今のタスクのスレッドID
  return threadId;
 }
 
 inline int Begin()
 {
  return i_st;
 }
 inline int End()
 {
  return i_ed;
 }
 
 inline bool Condition(int loopCounter)
 {
  return (!(*break_flag_) && loopCounter < i_ed);
 }
 
 inline void LoopBreak()
 {
  *break_flag_ = true;
 }
};
#define MY_LOOP_BREAK( omp ) omp.LoopBreak();continue