openmp中带有嵌套循环的并行部分代码
Parallel sections code with nested loops in openmp
我编写了这个并行代码来共享迭代,例如 first 和 last,fisrst+1 和 last-1,...但是我不知道如何改进这两个并行部分中每个部分的代码,因为我在部分中有一个内部循环,我想不出任何方法来简化它,谢谢。
这不是关于哪些值存储在 x 或 y 中,我使用此部分设计是因为必要条件是执行从 0 到 N 的迭代,例如:0 N、1 N-1、2 N-2 但是我想知道我是否可以优化维护此模型的内部循环
int x = 0, y = 0,k,i,j,h;
#pragma omp parallel private(i, h) reduction(+:x, y)
{
#pragma omp sections
{
#pragma omp section
{
for (i=0; i<N/2; i++)
{
C[i] = 0;
for (j=0; j<N; j++)
{
C[i] += MAT[i][j] * B[j];
}
x += C[i];
}
}
#pragma omp section
{
for (h=N-1; h>=N/2; h--)
{
C[h] = 0;
for (k=0; k<N; k++)
{
C[h] += MAT[h][k] * B[k];
}
y += C[h];
}
}
}
}
x = x + y;
使用部分似乎是错误的方法。 pragma omp for
似乎更合适。另请注意,您忘记声明 j
私有。
int x = 0, y = 0,k,i,j;
#pragma omp parallel private(i,j) reduction(+:x, y)
{
# pragma omp for nowait
for(i=0; i<N/2; i++) {
// local variable to make the life easier on the compiler
int ci = 0;
for(j=0; j<N; j++)
ci += MAT[i][j] * B[j];
x += ci;
C[i] = ci;
}
# pragma omp for nowait
for(i=N/2; i < N; i++) {
int ci = 0;
for(j=0; j<N; j++)
ci += MAT[i][j] * B[j];
y += ci;
C[i] = ci;
}
}
x = x + y;
此外,我不确定,但如果您只想将 x
作为最终输出,则可以进一步简化代码:
int x=0, i, j;
#pragma omp parallel for reduction(+:x) private(i,j)
for(i=0; i < N; ++i)
for(j=0; j < N; ++j)
x += MAT[i][j] * B[j];
一个部分只有一个线程,因此您不能使循环并行。怎么样
- 在顶层对
N
进行并行循环,
- 然后在每次迭代中使用一个条件来决定是否累加到
x,y
?
虽然@Homer512 的解决方案对我来说也是正确的。
section 构造是将不同的任务分配给不同的线程,每个 section 块标记不同的任务,因此您将无法按照您想要的顺序进行迭代我在这里回答你:
但我想澄清一下,使用sections的要求是每个块必须独立于其他块。
我编写了这个并行代码来共享迭代,例如 first 和 last,fisrst+1 和 last-1,...但是我不知道如何改进这两个并行部分中每个部分的代码,因为我在部分中有一个内部循环,我想不出任何方法来简化它,谢谢。
这不是关于哪些值存储在 x 或 y 中,我使用此部分设计是因为必要条件是执行从 0 到 N 的迭代,例如:0 N、1 N-1、2 N-2 但是我想知道我是否可以优化维护此模型的内部循环
int x = 0, y = 0,k,i,j,h;
#pragma omp parallel private(i, h) reduction(+:x, y)
{
#pragma omp sections
{
#pragma omp section
{
for (i=0; i<N/2; i++)
{
C[i] = 0;
for (j=0; j<N; j++)
{
C[i] += MAT[i][j] * B[j];
}
x += C[i];
}
}
#pragma omp section
{
for (h=N-1; h>=N/2; h--)
{
C[h] = 0;
for (k=0; k<N; k++)
{
C[h] += MAT[h][k] * B[k];
}
y += C[h];
}
}
}
}
x = x + y;
使用部分似乎是错误的方法。 pragma omp for
似乎更合适。另请注意,您忘记声明 j
私有。
int x = 0, y = 0,k,i,j;
#pragma omp parallel private(i,j) reduction(+:x, y)
{
# pragma omp for nowait
for(i=0; i<N/2; i++) {
// local variable to make the life easier on the compiler
int ci = 0;
for(j=0; j<N; j++)
ci += MAT[i][j] * B[j];
x += ci;
C[i] = ci;
}
# pragma omp for nowait
for(i=N/2; i < N; i++) {
int ci = 0;
for(j=0; j<N; j++)
ci += MAT[i][j] * B[j];
y += ci;
C[i] = ci;
}
}
x = x + y;
此外,我不确定,但如果您只想将 x
作为最终输出,则可以进一步简化代码:
int x=0, i, j;
#pragma omp parallel for reduction(+:x) private(i,j)
for(i=0; i < N; ++i)
for(j=0; j < N; ++j)
x += MAT[i][j] * B[j];
一个部分只有一个线程,因此您不能使循环并行。怎么样
- 在顶层对
N
进行并行循环, - 然后在每次迭代中使用一个条件来决定是否累加到
x,y
?
虽然@Homer512 的解决方案对我来说也是正确的。
section 构造是将不同的任务分配给不同的线程,每个 section 块标记不同的任务,因此您将无法按照您想要的顺序进行迭代我在这里回答你:
但我想澄清一下,使用sections的要求是每个块必须独立于其他块。