如何使用 OpenMP 在线程之间平等地并行化两个 for 语句?

How can I paralelize two for statements equally between threads using OpenMP?

假设我有以下代码:

#pragma omp parallel for
for  (i = 0; i < array.size; i++ ) {
   int temp = array[i];
   for (p = 0; p < array2.size; p++) {
      array2[p] = array2[p] + temp;

当我在第一行执行 #pragma omp parallel for 时,如何在我调用的线程之间划分 array2.size?对于我在执行 #pragma omp parallel for 时的理解,我将以这样的方式生成多个线程,每个线程都将拥有 array.size 的一部分,以便 i 永远不会相同线程之间。但在这种情况下,我还希望那些相同的线程具有 array2.size 的不同部分(它们的 p 也永远不会相同),这样我就不会让所有线程都进行相同的计算在第二个中。

我试过 collapse 表示法,但似乎只用于完美的 for 语句,因为我无法得到我想要的结果。

感谢任何帮助!提前致谢

您的代码的问题是多个线程将尝试同时修改 array2(竞争条件)。通过重新排序循环可以很容易地避免这种情况。如果 array2.size 没有提供足够的并行性,您可以应用 collapse 子句,因为循环现在是规范形式。

#pragma omp parallel for
for (p = 0; p < array2.size; p++) {
    for (i = 0; i < array.size; i++ ) {
        array2[p] += array[i];
    }
}

虽然 loads/stores 和计算之间的比率非常糟糕,但您不应该对此抱有太大期望。毫无疑问,这是内存限制而不是计算限制。

编辑:如果这真的是你的问题,而不仅仅是一个最小的例子,我也会尝试以下操作:

#pragma omp parallel 
{
    double sum = 0.;
    #pragma omp for reduction(+: sum)
    for (i = 0; i < array.size; i++) {
        sum += array[i];
    }
    #pragma omp for
    for (p = 0; p < array2.size; p++) {
        array2[p] += sum;
    }
}