OpenMP对不在for循环内的顺序函数进行并行化

时间:2019-05-03 11:07:01

标签: c++ multithreading openmp

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循环中。

我的尝试如下,这似乎有点round回,因为我必须明确地引入一个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 objX构造中通过引用传递大对象parallel for会对性能产生影响吗?由于它是一个大对象,因此无论如何我还是以引用的方式传递它,但是在将其放入OpenMP parallel for构造中时,我是否应该特别担心呢?

(2)如上所述,由于我必须引入一个新函数foox,并且在foox中,我不得不检查基于{{ 1}}。

1 个答案:

答案 0 :(得分:1)

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

请不要-除非绝对无法避免。此外,您的示例缺少#endif。您以此来烧伤自己或他人,您受苦。而不是使用if constexpr-或仅使用常规constconstexpr。很好。

2。这是OpenMP部分的用例

您的代码看起来像

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

3。避免比赛条件

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

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