不在 for 循环内的顺序函数的 OpenMP 并行化
Posted
技术标签:
【中文标题】不在 for 循环内的顺序函数的 OpenMP 并行化【英文标题】:OpenMP Parallelization of sequential functions that are not within a for loop 【发布时间】:2019-05-03 11:07:00 【问题描述】:GlobalDefines.h
有以下#defined
#define FOO_1 true//true if function void foo1() should run, false otherwise
#define FOO_2 false//true if function void foo2() should run, false otherwise
在src.cpp
内,这些是这样使用的:
#include GlobalDefines.h
class BigClassX
std::vector<int>...;
....
;
BigClassX ObjX;
int main()
#if FOO_1
foo1(objX);
#if FOO_2
foo2(objX);
foo1
(同样foo2
)通过引用接受它的参数:
void foo1(class BigClassX& objX)
我想并行化foo1
和foo2
,即使它们不在for
循环中。
我的尝试如下,似乎有点迂回,因为我必须明确引入for
循环:
#pragma omp parallel for
for(int i = 1; i <= 2; i++)
foox(i, objX);
现在,foox
是这样的:
void foox(int indicator, class BigClassX& objX)
if(FOO_1 && indicator == 1)
foo1(objX);
if(FOO_2 && indicator == 2)
foo2(objX);
还有其他方法可以在 OpenMP 中并行化吗?我对上述方法的担忧是:
(1) 在 OpenMP parallel for
构造中通过引用传递大对象 objX
是否会影响性能?由于它是一个大对象,我还是通过引用传递它,但是在将它放在 OpenMP parallel for
构造中时有什么特别要担心的吗?
(2)如上所述,由于我必须引入一个新函数foox
,并且在foox
内,我必须根据indicator
检查要调用哪个函数。
【问题讨论】:
你的问题比较笼统。我提供了一个笼统的答案。我担心它可能对您来说太笼统而无用。如果这不能完全帮助你,如果你会更好,请发布一个后续问题,您在其中以minimal reproducible example 的形式清楚地描述实际用例。 【参考方案1】:1。不要像这样滥用预处理器。
只是不要 - 除非它是绝对不可避免的。除了您的示例缺少#endif
。你会因此而灼伤自己或他人,你会受苦。而不是使用if constexpr
- 或者只是一个常规的const
或constexpr
。这很好。
2。这是 OpenMP 部分的用例
你的代码看起来像
#pragma omp parallel sections
#pragma omp section
foo1(objX);
#pragma omp section
foo2(objX);
3。避免竞争条件
一般来说,该对象在各部分之间共享,并且将相同的引用传递给foo1
和foo2
。并行处理共享对象是危险的。您必须避免对objX
中相同的leaf 元素(单个值)进行任何访问,除非所有 部分只读。
根据您的具体情况,您可以使用atomic
操作或critical
部分来防止竞争条件。
【讨论】:
感谢预处理器的指针。我将研究 constexpr。我使用#defines 的原因是我的项目不是很大,所以重新编译不是那么困难/耗时。此外,当包含在#if 中时,IDE 在代码的活动和非活动子部分之间显示不同以上是关于不在 for 循环内的顺序函数的 OpenMP 并行化的主要内容,如果未能解决你的问题,请参考以下文章
在 OpenMP 中并行化嵌套循环并使用更多线程执行内部循环
如何打破递归函数内的 for 循环并在 Javascript 中返回?