2016-10-06 69 views
0

我幾乎沒有使用OpenMP的經驗。我試圖運行一個for循環並行調用另一個外部函數。我正在使用MinGW編譯程序,所以不幸的是我沒有得到任何指示我做錯的錯誤,當我嘗試在我的循環外部添加一個並行程序時,程序根本無法運行。 findCombinations()是一個相當大的函數,它自己調用另一個函數。我想知道在這種情況下是否可以使用並行for循環?如果是這樣,有什麼我做的公然錯誤?OpenMP - 在並行for循環中調用外部函數

#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()

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; 
} 

我認爲這個問題可能是findCombinations()修改指針我發微博,* B,可能導致競爭條件。我的問題是我不確定如何解決它。

+0

請提供一個完整的示例,以便我們能夠更好地幫助您。首先想到的是 - 確保在編譯器中啓用OpenMP支持。例如,如果你在Linux上使用GCC,那麼你需要在編譯字符串中包含'-fopenmp'。 – David

+0

抱歉 - 現在添加了由它調用的函數。我使用的是windows,我已經安裝了MinGW來編譯gcc,只需通過命令行編譯-fopenmp –

+0

當然,你的所有線程都使用同一個指針'b'。它變得更糟,同時意識到'findCombinations()'是一個遞歸函數。你應該可以通過在這裏和那裏使用一些「關鍵」部分來解決這個問題,但我懷疑最後的加速是值得的。如果你需要表現,你最好認真反思一下你的算法。 – Gilles

回答

0

使用來自其他庫的函數在OpenMP並行區域內是完全有效的,只要這些庫提供線程安全的例程,否則您可能會受到無法控制的數據競爭,因此您只能進行一次例程調用一次。

如果你不確定你的程序是否是線程安全的,你可以嘗試使用一些工具,如Valgrind的helgrind或GCC/LLVM的thread sanitizer