1

以下に示す回路図コードは、 を削除すると正常に動作 しますが、これを使用するとコードはコンパイルされますが、バイナリを実行すると や#pragma omp parallel forのようなエラーが発生します。その理由は、複数のスレッドが変数またはに書き込もうとするためだと推測しています。これを修正するにはどうすればよいですか? 変数が共有されていることを伝える方法はありますか? または、このループを並行して実行する別の方法があります。私は `openmp をまったく初めて使用します。これを使用するのはこれが初めてです。*** glibc detected *** ./testBin: double free or corruption (!prev): 0x0c43d8d8 ***core dumpedomega, ell, ....lineVec

#include <omp.h>


int main( int argc , char **argv )
{ 
 vector <vector<string>> fileVec;
 //some code that reads in a CSV file lines into elements of fileVec

//variables constituting a line:
//my_float has been typedef to be a high precision class in real code
my_float omega;
my_float ell;

my_float init1Real;
my_float init1Imag;
my_float dinit1Real;
my_float dinit1Imag;

my_float init2Real;
my_float init2Imag;
my_float dinit2Real;
my_float dinit2Imag;

#pragma omp parallel for private(lineVec,fileVec,ell,omega,init1Real,init1Imag,dinit1Real,dinit1Imag,init2Real,init2Imag,dinit2Real,dinit2Imag)
 for (size_t i=0; i< fileVec.size(); i++) 
    { 

        lineVec=fileVec[i];


         ell=lineVec[0];
         omega=lineVec[1];

         init1Real=lineVec[2];
         init1Imag=lineVec[3];
         dinit1Real=lineVec[4];
         dinit1Imag=lineVec[5];
         init2Real=lineVec[6];
         init2Imag=lineVec[7];
         dinit2Real=lineVec[8];
         dinit2Imag=lineVec[9];


        // cout<<"OUTPUT ell=" << ell<< " omega=" << omega <<" init1Real="<<init1Real<<endl;

         //do some other calc involving these variables

    }     
   }
4

2 に答える 2

5

共有からの読み取りfileVec スレッドセーフです。タイプの変数のみをmy_float作成するか、それ以上にする必要がprivateあります-ループ内で宣言します:

int main(int argc, char **argv)
{
    vector<vector<string>> fileVec;

    //some code that reads in a CSV file lines into elements of fileVec

    #pragma omp parallel for private(lineVec)
    for (size_t i = 0; i < fileVec.size(); i++)
    {
        lineVec = fileVec[i];

        //my_float has been typedef to be a high precision class in real code

        my_float ell = lineVec[0];
        my_float omega = lineVec[1];

        my_float init1Real = lineVec[2];
        my_float init1Imag = lineVec[3];
        my_float dinit1Real = lineVec[4];
        my_float dinit1Imag = lineVec[5];
        my_float init2Real = lineVec[6];
        my_float init2Imag = lineVec[7];
        my_float dinit2Real = lineVec[8];
        my_float dinit2Imag = lineVec[9];

        cout << "OUTPUT ell=" << ell << " omega=" << omega
             << " init1Real=" << init1Real << endl;

        //do some other calc involving these variables
    }
}

my_floatがスレッドセーフでないか、//do some other calc involving these variables.

最近の OpenMP バージョンでは、ランダム アクセス イテレータを提供するため、イテレータを使用してベクトルをウォークすることもできることに注意してください。

typedef vector<vector<string>>::const_iterator iterType;

#pragma omp parallel for private(lineVec)
for (iterType it = lineVec.begin(); it != lineVec.end(); it++)
{
    ...
}
于 2012-12-06T09:37:54.617 に答える
1

あなたが書いた方法では、openmp はいくつかのスレッドを作成し、すべてのスレッド間で for ループの合計反復回数を分割します。そうすることで、異なるスレッドが共有するベクトルで並列読み取りを実行しようとします。データ共有属性を変更できます (データ共有属性句については OpenMP Wikiを参照してください。このmicrosoft docには、その方法の良い例があります。たとえば、lineVec と fileVec を「プライベート」として宣言するには、次のように使用します。

#pragma omp parallel private(lineVec, fileVec)

さらに、cout はスレッド セーフではなく、複数のスレッドからの cout の呼び出しもシリアル化する必要があります。

于 2012-12-05T22:28:02.740 に答える