OpenMP並列化(forループ内にberakがある場合)
#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)
{
{
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)
{
//並列化されているときの今のタスクのスレッドID
threadId = omp_get_thread_num();
//並列化の分割ステップ
int n = (loopNum_ + threadNum_ -1 )/threadNum_;
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 );
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 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;
}
};
{
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