OpenMP 不在 for 循环中的顺序函数的并行化

OpenMP Parallelization of sequential functions that are not within a for loop

本文关键字:顺序 并行化 函数 不在 for 循环 OpenMP      更新时间:2023-10-16

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){}

我想并行化foo1foo2即使它们不在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)在 OpenMPparallel for构造中通过引用传递大对象objX是否会对性能造成影响?由于它是一个大对象,我无论如何都会通过引用传递它,但是在将其放置在 OpenMPparallel for构造中时,我应该特别担心什么吗?

(2)如上所述,这似乎有点圆,因为我必须在foox引入一个新函数,并且在foox中我必须根据indicator检查要调用哪个函数。

1. 不要像这样滥用预处理器。

只是不要 - 除非它是绝对不可避免的。除了你的例子是缺少#endif.你会用这个烧伤自己或别人,你会受苦。而不是使用if constexpr- 或者只是常规的,如果在constconstexpr.这很好。

2. 这是 OpenMP 部分的用例

您的代码看起来像

#pragma omp parallel sections
{
#pragma omp section
{
foo1(objX);
}
#pragma omp section
{
foo2(objX);
}
}

3. 避免竞争条件

通常,此对象在各节之间共享,并将相同的引用传递给foo1foo2。并行处理共享对象是危险的。您必须避免访问objX中的相同元素(单个值),除非仅读取所有部分。

根据您的具体情况,您可以使用atomic操作或critical部分来防止争用条件。