【问题标题】:OpenMP - Calling external functions in a parallel for loopOpenMP - 在并行循环中调用外部函数
【发布时间】:2016-10-06 19:23:28
【问题描述】:

我很少有使用 OpenMP 的经验。我正在尝试并行运行一个调用另一个外部函数的 for 循环。我正在用 MinGW 编译程序,所以不幸的是,我没有收到任何表明我做错了什么的错误,当我尝试在循环之外添加并行时,程序根本不会运行。 findCombinations() 是一个相当大的函数,它本身调用另一个函数。我想知道在这种情况下是否可以使用并行 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,这可能导致竞争条件。我的问题是我不确定如何解决它。

【问题讨论】:

  • 请提供完整的示例,以便我们更好地帮助您。首先想到的是 - 确保在编译器中启用 OpenMP 支持。例如,如果您在 Linux 上使用 GCC,则需要在编译字符串中包含 -fopenmp
  • 抱歉 - 现在添加了它调用的函数。我正在使用 windows 并且我已经安装了 MinGW 来使用 gcc 编译,只需通过命令行使用 -fopenmp 进行编译
  • 当然你的所有线程都在同一个指针b上工作有问题。当意识到findCombinations() 是一个递归函数时,情况会变得更糟。您应该可以通过在这里和那里使用一些critical 部分来解决这个问题,但我怀疑最终的加速是否值得。如果您需要性能,最好认真重新考虑您的算法。

标签: c multithreading parallel-processing openmp


【解决方案1】:

如果这些库提供线程安全例程,则在 OpenMP 并行区域内使用来自其他库的函数是完全有效的,否则您可能会遇到无法控制的数据竞争,因此您只能在一次。

如果您不确定您的程序是否是线程安全的,您可以尝试使用一些工具,例如 Valgrind 的 helgrind 或 GCC/LLVM 的 thread sanitizer

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-18
    • 2021-09-11
    • 2016-07-23
    • 1970-01-01
    • 2013-12-08
    相关资源
    最近更新 更多