如何解决C ++代码的三个循环的并行化?
如何使用openmp并行处理此代码: xp,yp,zp,gpx,gpy和gpz是已知的一维向量。
for (ies = 0; ies < 1000000; ies++){
for (jes = ies+1; jes < 1000000; jes++){
double dxp = xp[ies] - xp[jes];
double dyp = yp[ies] - yp[jes];
double dzp = zp[ies] - zp[jes];
double distance = sqrt( dxp * dxp + dyp * dyp + dzp * dzp );
double gpspec = gpx[ies] * gpx[jes] + gpy[ies] * gpy[jes] + gpz[ies] * gpz[jes];
#pragma omp parallel for
for (kes = 1; kes <= 100; kes++){
double distan = kes * distance;
E1[kes] = E1[kes] + gpspec * sin(distan) / distan;
}
}
}
解决方法
这是一种可能性(未经测试)
#pragma omp parallel for reduction(+: E1) private(jes,kes) schedule(dynamic)
for (ies = 0; ies < 1000000; ies++){
for (jes = ies+1; jes < 1000000; jes++){
double dxp = xp[ies] - xp[jes];
double dyp = yp[ies] - yp[jes];
double dzp = zp[ies] - zp[jes];
double distance = sqrt( dxp * dxp + dyp * dyp + dzp * dzp );
double gpspec = gpx[ies] * gpx[jes] + gpy[ies] * gpy[jes] + gpz[ies] * gpz[jes];
for (kes = 1; kes <= 100; kes++){
double distan = kes * distance;
E1[kes] = E1[kes] + gpspec * sin(distan) / distan;
}
}
}
我放置了schedule(dynamic)
来尝试补偿由循环所覆盖的索引域ies * jes
的三角形引起的线程之间的工作负载不平衡。
同样,取决于定义E1
的方式,编译器可能会接受也可能不会接受。但是无论如何,如果不接受reduction(+: E1)
,总有可能使用critical
构造手动进行归约。
您最里面的循环中已经有一个tidyr::pivot_longer(df,cols = starts_with('VaRevt'),names_to = 'Hour'
names_pattern = 'VaRevt(\\d+)')
编译指示。为此,您可能需要通过设置编译器标志(例如,对于GCC编译器套件,将是omp parallel for
标志)来在编译器中启用OpenMP支持。您可能还需要-fopenmp
#include
标头。
但是,话虽如此,我怀疑您将从这种并行化中获得很多好处,因为您要并行化的循环的一次运行不会做太多工作。与并行化相关的运行时开销抵消了同时运行多个循环迭代的收益,因此我认为您不会有太多的收获。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。