繁体   English   中英

openmp中带有嵌套循环的并行部分代码

[英]Parallel sections code with nested loops in openmp

我制作了这个并行代码来共享迭代,例如 first 和 last、first+1 和 last-1,... 但是我不知道如何改进两个并行部分中的每个部分的代码,因为我有一个内部循环在这些部分中,我想不出任何方法来简化它,谢谢。

这与将哪些值存储在 x 或 y 中无关,我使用此部分设计,因为必要条件是执行从 0 到 N 的迭代,例如:0 N、1 N-1、2 N-2 但我想知道如果我可以优化维护这个 model 的内部循环

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作为您的最终 output,您可以进一步简化代码:

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];

一个部分只有一个线程,所以你不能使循环并行。 怎么样

  1. 在顶层对N做一个并行循环,
  2. 然后在每次迭代中使用条件来决定是否累积到x,y

尽管@Homer512 的解决方案对我来说也是正确的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM