2016-10-06 12 views
0

OpenMPを使用した経験はほとんどありません。別の外部関数を呼び出すforループを並列に実行しようとしています。私はMinGWでプログラムをコンパイルしていますので、残念ながら私が間違っていることを示すエラーは一切発生しません。私のループ外に並列を追加しようとするとプログラムは単に実行されません。 findCombinations()は、別の関数自体を呼び出すかなり大きな関数です。このシナリオで並列forループを使用することが可能かどうか疑問に思っていますか?もしそうなら、私は大騒ぎに間違って何かをしていますか?ここでOpenMP - 並列ループで外部関数を呼び出す

#pragma omp parallel for 
for(int j = 0; j < n[i].count; j++) { 
    int length = 0; 
    while(n[i].neighbourhoods[j][length].index != -1) length++; 
    bool used[length]; 
    memset(used, false, sizeof(used)); 
    findCombinations(&b, n[i].neighbourhoods[j], length, 0, 0, used, n[i].col); 
    free(n[i].neighbourhoods[j]); 
} 

は)私は問題がfindCombinations(ということかもしれないと思うfindCombinations()

int findCombinations(struct blocks *b, struct element neighbourhood[], int neighbourhoodSize, int start, int currLen, bool used[], int col) {  
    if (currLen == blocksize) { 
     b->blocks[b->count].elements = malloc((blocksize+1) * sizeof(struct element)); 
     b->blocks[b->count].col = col; 
     int blockCount = 0; 
     for (int i = 0; i < neighbourhoodSize; i++) { 
      if (used[i] == true) { 
       b->blocks[b->count].elements[blockCount++] = neighbourhood[i]; 
      } 
     } 
     b->blocks[b->count].elements[blocksize] = neighbourhood[neighbourhoodSize]; //ensures the last item is -1 
     b->blocks[b->count].signature = getSignature(b->blocks[b->count].elements); 
     return 1; 
    } 
    if (start == neighbourhoodSize) { 
     return 0; 
    } 
    int new = 0; 

    used[start] = true; 
    b->count += findCombinations(b, neighbourhood, neighbourhoodSize, start + 1, currLen + 1, used, col); 

    used[start] = false; 
    b->count += findCombinations(b, neighbourhood, neighbourhoodSize, start + 1, currLen, used, col); 

    return new; 
} 

である可能性が競合状態を引き起こし、B *、私はそれに送信ポインタを変更します。私の問題は、それを回避する方法がわかりません。

+0

私たちがより効果的に役立つように完全な例を提供してください。最初に、あなたのコンパイラでOpenMPサポートが有効になっていることを確認しました。たとえば、LinuxでGCCを使用する場合、コンパイル文字列に '-fopenmp'を含める必要があります。 – David

+0

申し訳ありません - ここで呼び出された関数が追加されました。私はウィンドウを使用していて、gccでコンパイルするためにMinGWをインストールしました。コマンドラインで-fopenmpを使ってコンパイルするだけです。 –

+0

もちろん、同じポインタ 'b'を扱うすべてのスレッドで問題があります。 'findCombinations()'が再帰関数であることを認識している間はさらに悪化します。おそらく、ここではいくつかの「重要な」セクションを使って修正できるはずですが、最終的なスピードアップがそれに値するとは思えません。パフォーマンスが必要な場合は、アルゴリズムを真剣に考え直すことをお勧めします。 – Gilles

答えて

0

他のライブラリの関数を使用すると、スレッドセーフなルーチンを提供するOpenMP並列領域内で完全に有効になります。そうしないと、制御できないデータ競合が発生する可能性があります。したがって、一度に。

プログラムがスレッドセーフであるかどうかわからない場合は、ValgrindのhelgrindまたはGCC/LLVMのthread sanitizerのようなツールを使用できます。

関連する問題