如何使用 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;
}
}
假设我有以下代码:
#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;
}
}