2017-03-15 5 views
0

プログラムを並列化するために#pragmaディレクティブを使用しました。それがなければ、すべてうまく動作します。アレイでのC++プラグマompセグメンテーションフォールト(データ競合?)

残念ながら、並列化でいくつかの関数で使用されるため、グローバルに宣言する必要がある複雑な配列を使用します。私が理解する限り、技術的には、これは世界的に保存されているので、これは違いはありません。

ただし、問題のあるアレイは私的に使用されます。私が他の議論から理解したことから、並列化が始まる前に配列にメモリを割り当てて、プログラムがすべてのスレッドに対して正しくメモリを確保するようにしなければなりません。スレッド内で私は再びメモリを割り当てます。サイズ(行列サイズ)は変更されません。

しかし、スレッド内のデータ(配列 "度")をテストするためにnum_threads(1)を設定しても、結局は壊れてしまいます。

以前のバージョンでは、スレッド内で配列を宣言し、関数を使用しませんでした。すべてがうまくいきましたが、今はあまりにも面倒です。

私はコードを減らそうとしました。それが理解できることを願っています。私はgccを使ってそれをコンパイルします。

申し訳ありませんが、私は問題を把握することはできません。私はいくつかのアドバイスに感謝します。

最高

、 マティアスは

#include <omp.h> 
int matrixsize=200; 
vector<int> degree; 
vector<list<int> >adjacency; 
vector<vector<bool> >admatrix; 
vector<vector<float> > geopos; 

\\[...] 

void netgen(); 
void runanalyses(); 

\\[...] 

int main(int argc, char *argv[]) 
{ 

\\[...] 

adjacency.assign(matrixsize,list<int>()); 
admatrix.assign(matrixsize, vector<bool>(matrixsize, 0)); 
degree.assign(matrixsize,0); 
geopos.assign(matrixsize,vector<float> (dim,0)); 

#pragma omp parallel for shared(degdist,ADC,ADCnorm,ACC,ACCnorm,its,matrixsize) private(adjacency,admatrix,degree,geopos) num_threads(1) 
for (int a=0;a<its;a++) 
{ 
    adjacency.assign(matrixsize,list<int>()); 
    admatrix.assign(matrixsize, vector<bool>(matrixsize, 0)); 
    degree.assign(matrixsize,0); 
    geopos.assign(matrixsize,vector<float> (dim,0)); 

    netgen(); 
    runanalyses(); 

} // for parallelization 

\\[...] 

} 

答えて

0

は残念ながら、私は、彼らが並列内のいくつかの機能に使用されているので、全体的に宣言する必要があり、複雑な配列を使用しています。私が理解する限り、技術的には、これは世界的に保存されているので、これは違いはありません。

あなたは本当にそうすべきではありません!並列領域内のグローバルデータ構造を変更すると、データ競合の理由を判断することが非常に困難になります。代わりに、適切なインサーフェスを定義します。 (const)参照によってベクトルを渡す。たとえば、並列領域のconst std::vector&で安全に操作できます。

グローバル状態を解消しても問題が発生した場合は、適切なフォローアップの質問をしてください。Minimal, Complete, and Verifiable example(そのページをよく読んでください)と特定のエラーの説明あなたはそれをデバッグしようとしています。

+0

ありがとうZulan!私はそれを調べるでしょうが、実際に後で質問をするかもしれません。 – thiasma

関連する問題