不在 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&amp; 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) 在 OpenMP parallel for 构造中通过引用传递大对象 objX 是否会影响性能?由于它是一个大对象,我还是通过引用传递它,但是在将它放在 OpenMP parallel for 构造中时有什么特别要担心的吗?

(2)如上所述,由于我必须引入一个新函数foox,并且在foox 内,我必须根据indicator 检查要调用哪个函数。

p>

【问题讨论】:

你的问题比较笼统。我提供了一个笼统的答案。我担心它可能对您来说太笼统而无用。如果这不能完全帮助你,如果你会更好,请发布一个后续问题,您在其中以minimal reproducible example 的形式清楚地描述实际用例。 【参考方案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 部分来防止竞争条件。

【讨论】:

感谢预处理器的指针。我将研究 constexpr。我使用#defines 的原因是我的项目不是很大,所以重新编译不是那么困难/耗时。此外,当包含在#if 中时,IDE 在代码的活动和非活动子部分之间显示不同

以上是关于不在 for 循环内的顺序函数的 OpenMP 并行化的主要内容,如果未能解决你的问题,请参考以下文章

运行方法并等待完成所有 for 循环 openmp

Openmp 程序在没有临界区的情况下工作

在 OpenMP 中并行化嵌套循环并使用更多线程执行内部循环

如何打破递归函数内的 for 循环并在 Javascript 中返回?

使用 OpenMP 在 C、C++ 中并行化嵌套 for 循环的几种方法之间的区别

强制 OpenMP 不在每个线程中缓存大对象