如何将openMP的外循环与串行内循环并行化以添加数组
How to parallellize an outer loop with openMP with serial inner loop for array addition
以下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);
}
}
如您所见(第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线程上合理)。您甚至可以获得较慢的并行化循环。这是因为创建新线程的开销非常高(加上一些其他额外的东西,比如破坏线程)。
因此,您必须通过并行化循环获得比创建线程所需更多的时间。
希望这能回答你的问题。
如果你仍然需要一个更快的Programm,你可以考虑一种算法来并行内部循环(例如,通过分割迭代空间和使用openmp约简结构)
相关文章:
- 如何使用 OpenMP 正确并行化 for 循环?
- 嵌套循环 OpenMP 并行化、私有索引还是公共索引?
- 如何并行化增加循环的大小
- 在 C++ 中使用 OpenMP 并行化两个 for 循环不会提供更好的性能
- OpenMP C++:并行化 for 循环的负载不平衡
- 将 for 循环与嵌套的 while 循环并行化时出现 OpenMP 分段错误
- 如何在 OpenACC 中并行化内部具有"min"功能的循环
- 在 C 中并行化嵌套循环的几种方法之间的差异,C++使用 OpenMP
- OpenMP 不在 for 循环中的顺序函数的并行化
- "->"的循环承载依赖性阻止了并行化
- 如何并行化矩阵排序以进行循环
- 使用 c++17 算法并行化简单循环
- 是否可以使用CUDA并行化此嵌套进行循环
- 使用 CUDA 并行化四个或更多嵌套循环
- 如何将openMP的外循环与串行内循环并行化以添加数组
- 与串行相比,openMP 并行化 for 循环的速度更慢
- C++ 2011 : std::thread:并行化循环的简单示例
- 用openmp实现循环并行化的嵌套c++
- OpenMP for循环并行化:我的代码效率很低
- 融合一个三角形循环并行化,计算子指标