多くの反復を実行するコードがあり、条件が満たされた場合にのみ、反復の結果が保存されます。これは自然にwhileループとして表現されます。私は、各実現が独立しているので、コードを並列に実行しようとしています。 、OpenMP whileループ
while(nit<avit){
#pragma omp parallel shared(nit,avit)
{
//do some stuff
if(condition){
#pragma omp critical
{
nit++;
\\save results
}
}
}//implicit barrier here
}
と、これは正常に動作します...しかし、私は、並列ブロック内でやっているものは他よりも一回の反復に長い時間がかかる場合ことを意味し、それぞれ実現後の障壁が、そこにある:だから私はこれを持っていますすべてのスレッドは、次の繰り返しを続行するのではなく、完了を待っています。
スレッドが機能し続けるように、この障壁を回避する方法はありますか?私は何千もの反復を平均しているので、もう少し傷ついてはいけません(nit
変数が既に実行中のスレッドでインクリメントされていない場合)...
私はこれを並列にしましたが、 forループの自動増分は、nit
変数をワイルドにします。これは私の試みです:
#pragma omp parallel shared(nit,avit)
{
#pragma omp for
for(nit=0;nit<avit;nit++){
//do some stuff
if(condition){
\\save results
} else {
#pragma omp critical
{
nit--;
}
}
}
}
、もう1つは別のスレッドによってそれの増減から期待できるとして、それは...働くとループの周りに行く、予想通り、私nit
変数が予測不可能な値をとり続けます異なる時に。
私はforループのブランクで増分を残しても試してみましたが、それはコンパイルできない、または自分のコードをだまししようとするためのループに増分を持たないために、
...
incr=0;
for(nit=0;nit<avit;nit+=incr)
...
が、その後、私のようなコードがクラッシュする...
アイデア?
おかげ
編集:ここでは、whileループのコードの作業を最小限の例です:
#include <random>
#include <vector>
#include <iostream>
#include <time.h>
#include <omp.h>
#include <stdlib.h>
#include <unistd.h>
using namespace std;
int main(){
int nit,dit,avit=100,t,j,tmax=100,jmax=10;
vector<double> Res(10),avRes(10);
nit=0; dit=0;
while(nit<avit){
#pragma omp parallel shared(tmax,nit,jmax,avRes,avit,dit) private(t,j) firstprivate(Res)
{
srand(int(time(NULL))^omp_get_thread_num());
t=0; j=0;
while(t<tmax&&j<jmax){
Res[j]=rand() % 10;
t+=Res[j];
if(omp_get_thread_num()==5){
usleep(100000);
}
j++;
}
if(t<tmax){
#pragma omp critical
{
nit++;
for(j=0;j<jmax;j++){
avRes[j]+=Res[j];
}
for(j=0;j<jmax;j++){
cout<<avRes[j]/nit<<"\t";
}
cout<<" \t nit="<<nit<<"\t thread: "<<omp_get_thread_num();
cout<<endl;
}
} else{
#pragma omp critical
{
dit++;
cout<<"Discarded: "<<dit<<"\r"<<flush;
}
}
}
}
return 0;
}
私は他の人より長いを取って一つのスレッドをシミュレートするusleep
パーツを追加しました。プログラムを実行すると、すべてのスレッドはスレッド5が完了するのを待たなければならず、次の実行を開始します。私がしようとしているのは、このような待ち時間を避けることです。つまり、他のスレッドが5を待たずに次の繰り返しを選択したいと思っています。
*いくつかのものをより具体的に理解することなく、質問に正しく答えることは実際には不可能です。特に、何らかのものに* nitがアクセスされているかどうかと、複数のスレッドが同時に条件を持っているときに起こるはずのものや、あるスレッドが何らかのものをやっている間に複数回更新されたもの* ...それは難しいですが、良い、具体的な答えのためには、[mcve]を作成する必要があります。 – Zulan
コメントありがとう@Zulan。最後に最小限の作業例を追加するために質問を編集しました。これが事を明確にすることを願っています。 –