2016-10-06 51 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