データを生成する大きなループがあります。各反復は、例えば1秒を要し、データの塊を生成する。私はすべてのチャンクが正しい順序でファイルに書き込まれる必要があります。私はループを並列化したい場合はループ内のOpenMP同期
、私は(非常に簡略化)このような何かを書くことができ:これはファイルに私の出力を取得しますが、エントリの順序は保証されません
FILE* f = fopen("output.txt", "w");
omp_lock_t lock;
omp_init_lock(&lock);
int nIterations = 1000000;
#pragma omp parallel for
for(int thread=0; thread<4; thread++)
{
int a=0, b=0, c=0;
for(int n=thread; n<nIterations; n+=4)
{
int value = do_computations(&a, &b, &c);
omp_set_lock(&lock);
fprintf(f, "%d\n", value);
omp_unset_lock(&lock);
}
}
#pragma omp barrier
fclose(f);
omp_destroy_lock(&lock);
。
実行を同期して、すべてのスレッドが自分のタスクを実行してから、マスタスレッドがファイルに書き込みを行った後、スレッドを再開します。いくつかの不可解な理由のために、これは、OpenMP仕様で禁止されて、除き
#pragma omp parallel for
for(int thread=0; thread<4; thread++)
{
int a=0, b=0, c=0;
int values[4];
for(int n=thread; n<nIterations; n+=4)
{
values[n] = do_computations(&a, &b, &c);
#pragma omp barrier
if(thread == 0)
{
for(int i=0; i<4; i++)
fprintf(f, "%d\n", values[i]);
}
#pragma omp barrier
}
}
#pragma omp barrier
:つまり、私はこのような何かをしたいと思います。
または私は
#pragma omp parallel for
for(int thread=0; thread<4; thread++)
{
int a=0, b=0, c=0;
for(int n=thread; n<nIterations; n+=4)
{
int value = do_computations(&a, &b, &c);
#pragma omp ordered
{
fprintf(f, "%d\n", value);
}
}
}
#pragma omp barrier
fclose(f);
を試みることができる。しかしそのためには、いずれかの動作しません「と、ループの反復が構築物について...つ以上の注文指示を実行してはいけません。」
コードを1つのループとして書き直したくないので、ループを交換したくありません。
他のスレッド/同期ツールを使用せずにOpenMPでこれを行うには、きれいな方法がありますか?
コードを実行しているアーキテクチャ/オペレーティングシステムとは何ですか? – Raj
'parallel for'の代わりに' #pragma omp parallel'を使うことができますか? – Raj
'do_computations'は本当に3つの' 0'を渡していますか?私は 'do_computations'は純粋な関数ではない(つまり副作用がある)と仮定します。もしそうなら、 'do_computations'の副作用は何ですか? 'do_computations'への2回の呼び出しが並行して実行されるとどうなりますか?私は、あなたがそれらを並行して実行することによっても逃げることができることを非常に疑う(副作用があるという仮定に基づいて、したがって実行が発生する順序は問題*)。 - あるいはあなたはコードを単純化していますか?実際のループをよりよく表現できるものを共有するべきでしょうか? – ArjunShankar