如何将带有openMP的外部循环与串行内部循环并行化以添加数组

时间:2013-11-26 13:38:23

标签: c++ parallel-processing

C ++函数的以下片段最初是作为串行代码编写的。 为了将外循环与计数器'jC'并行化,我只添加了行“#pragma omp parallel for private(jC)”。尽管这种天真的方法对我有很多次帮助,但我怀疑是否足以并行化jC循环,因为相对于原始代码,执行时间似乎没有变化。 有没有人建议确保以下代码有效地转换为(正确的)并行代码?

如果我的问题没有得到很好的解答(这是我在这个论坛的第一篇文章),请提前致谢并道歉。

代码段是:

#include "omp.h"

void  addRHS_csource_to_pcellroutine_par(
             double *srcCoeff, double *srcVal, int nPc,
             double *adata, double *bdata, int elsize
             )
{   int elamax = elsize*elsize;
    int jC;
    #pragma omp parallel for private(jC)
    for (int jC=0; jC<nPc; jC++) {
         for (int el=0; el<elamax; el++) {

              adata[el + jC*elamax]    = adata[el + jC*elamax] - srcCoeff[el + jC*elamax];
         }

         for (int el=0; el<elsize; el++) {

              bdata[el + jC*elsize]    = bdata[el + jC*elsize] + srcVal[el + jC*elsize];

         }

    }
}

附加说明:一种(可能不是最优雅的?)解决方法,包括将代码更改为

void  addRHS_csource_to_pcellroutine_parFunction(int jC, int elamax,
             double *srcCoeff, double *srcVal, int nPc,
             double *adata, double *bdata, int elsize
             )
{   
    for (int el=0; el<elamax; el++) {

         adata[el + jC*elamax]    -= srcCoeff[el + jC*elamax];
    }

    for (int el=0; el<elsize; el++) {

         bdata[el + jC*elsize]  += srcVal[el + jC*elsize];

    }

}

void  addRHS_csource_to_pcellroutine_par(
             double *srcCoeff, double *srcVal, int nPc,
             double *adata, double *bdata, int elsize
             )
{   int elamax = elsize*elsize;  
    #pragma omp parallel for  
    for (int jC=0; jC<nPc; jC++) {
         addRHS_csource_to_pcellroutine_parFunction(jC, elamax, srcCoeff, srcVal, nPc, adata, bdata, elsize);
    }

}

1 个答案:

答案 0 :(得分:1)

正如您可以阅读specifcation(第55页) 你的内部循环没有并行化。只有外面的是。

int jC;
#pragma omp parallel for private(jC)
for (int jC=0;......

您已经定义了两个名为jC的变量。你打算做的是正确的,但你应该决定一个解决方案:

int jC;
#pragma omp parallel for private(jC)
for(jC = 0;....

#pragma omp parallel for
for(int jC = 0;....

至于:

  

我怀疑是否足以并行化jC循环,   因为执行时间似乎   相对于原始代码不变。

充足性取决于您必须执行的迭代次数(由nPc给出)以及您提供的线程数(合理地在四核8线程上)。 您甚至可以获得较慢的并行化循环。这是因为创建新线程的开销非常高(+其他一些额外的东西,如管理线程)。

因此,您需要通过并行化循环来获得比创建线程所需的更多时间。

希望这能回答你的问题。

如果您仍然使用更快的程序,您可以考虑使用并行化内部循环的算法(例如,通过拆分迭代空间并使用openmp reduction构造)