1
#include "/usr/lib/gcc/i686-linux-gnu/4.6/include/omp.h"
#include <iostream>
#include<list>
using namespace std;

int main()
{
    list<int> lst;
    for(int i=0;i<5;i++)
        lst.push_back(i);

#pragma omp parallel for
    for(int i=0;i<5;i++)
    {
        cout<<i<<" "<<omp_get_thread_num()<<endl;
    }   
}

私はこれを得ることができると仮定します:

0  0
1  0
2  0
3  1
4  1

ただし、次の結果が得られる場合があります。

30  0
1  0
2  0
  1
4  1

またはこの種の結果でさえ:

30 1 0
4 1

1 0
2 0

私はこれが出力コードのためであることを知っています:

cout<<i<<" "<<omp_get_thread_num()<<endl;

小さなセグメントにスプライスされており、出力を行うときに順序がありません。しかし、これを防ぐ方法を誰が教えてくれますか?ありがとう。

4

4 に答える 4

3

標準の出力ストリームは同期されていません!

標準が与える唯一の保証は、単一の文字がアトミックに出力されることです。

並列化のポイントに逆らうロックが必要です。または、「<< i」を削除すると、準同期動作が発生する可能性があります。

于 2013-01-24T10:27:38.590 に答える
1

ループの順序が狂っています。これが、順序付けられていない出力がある理由です。

あなたの問題30

30  0
1  0
2  0
 1
4  1

その後、涼しくしてください、ありません30が、3そして0。予想どおり、次の順序付けられていない行がまだあります[0..4]

3 0  0
1  0
2  0
 1
4  1

わからないのは、0どの1sがスレッド番号ではないかだけです。

于 2013-01-24T10:46:50.303 に答える
0

5どのスレッドがどのインデックスを処理したかを含む(サイズの)配列を作成し、それを並列ループの外側に出力できます。

于 2013-01-24T10:30:53.003 に答える
0

あなたのコード

#pragma omp parallel for
    for(int i = 0; i < 5; i++)
    {
        cout << i << " " << omp_get_thread_num() << endl;
    }

と同等です

#pragma omp parallel for
    for(int i = 0; i < 5; i++)
    {
        cout << i;
        cout << " ";
        cout << omp_get_thread_num();
        cout << endl;
    }

<<異なるスレッドでの呼び出しは、任意の順序で実行できます。たとえばcout << i;、スレッド3の後cout << i;にトレッド0が続きcout << " ";、スレッド3などの後に文字化けした出力が続く場合があります30 ...

cout <<正しい方法は、各スレッドがループ内で1回だけ呼び出すようにコードを書き直すことです。

#pragma omp parallel for
    for(int i = 0; i < 5; i++)
    {
        stringstream ss;
        ss << i << " " << omp_get_thread_num() << '\n';
        cout << ss.str();
    }   
于 2013-01-24T12:42:45.610 に答える