是否有任何干净的方法可以让OpenMP pragma使用宏?

时间:2018-05-23 20:18:29

标签: c c++11 macros openmp

我必须将OpenMP添加到客户的代码中。它有几个宏有点像这样:

int i, imax;
#ifdef MAC1
double x1, y1
#endif
#ifdef MAC2
double x2, y2
#endif

//first loop:
for (i=0; i<imax; i++ ) {
#ifdef MAC1
//process x1, y1
#endif
#ifdef MAC2
//process x2, y2
#endif
//do a ton of other stuff
}

// Lots more code.  No way it will all work in one omp region.

//second loop:
for (i=0; i<imax; i++ ) {
#ifdef MAC1
//process x1, y1
#endif
#ifdef MAC2
//process x2, y2
#endif
//do a ton of other stuff
}

完全有可能MAC1MAC2都可以定义,或者两者都定义,或者两者都不定义。

所以现在,我想在OpenMP下运行循环。这通常不起作用:

#pragma omp parallel private(x1, y1,   \
                             x2, y2,   \
                             and a     \
                             ton of    \
                             other stuff)
{
...
}

...因为如果未定义MAC1和/或MAC2,编译器会抱怨x1, y1和/或x2, y2未定义。

我想到了几种解决这个问题的方法,要么不起作用,要么不合标准:

1)我不能把这些变量的定义拉到omp并行区域,因为正如我所说,我将不得不在第二个区域使用它们,我不能在那里重新定义它们。

2)我想我可以将这些变量拉出宏块并定义它们是否需要它们。这将是最简单的解决方案,但这似乎有点“黑客”。我怀疑原则上有些情况无论如何都无法发挥作用。

3)我想我可以编写几个omp编译指示,每个宏组合一个,包含在四个不同的#ifdefs中,但是我需要四个不同的可选编译指示,代码将变得非常快速。

4)我尝试做类似

的事情
#pragma omp parallel private(the other stuff) \
#ifdef MAC1
                     private(x1, y1)   \
#endif
#ifdef MAC2
                     private(x2, y2)   \
#endif
{ ... }

这看起来仍然不太好看,但它会比四个不同的可选pragma好得多。不过,我尝试了几种语法变体,但编译器不知道我想要做什么。

任何人都知道干净的方式来做我想做的事情吗?

2 个答案:

答案 0 :(得分:3)

我能想到的最简单,最自然的事情就是:

// Just once, in a header if need be:

#ifdef MAC1
// Note trailing comma:
#define MAC1_VARS x1, y1,
#else
#define MAC1_VARS
#endif

#ifdef MAC2
// Note trailing comma:
#define MAC2_VARS x2, y2,
#else
#define MAC2_VARS
#endif
/////////////////////////

// ...

// each parallel region / loop:
#pragma omp parallel private(MAC1_VARS \
                         MAC2_VARS     \
                         other, stuff)
{
    // ...
}

MAC1_VARSMAC2_VARS因此适当扩展,无论是对于任何内容还是对变量列表的适当子序列。

如果您可以修改有条件地声明这些变量的客户端代码,那么我也会将MAC1_VARSMAC2_VARS的定义放在那里,而不是在单独的预处理器条件中。

答案 1 :(得分:1)

如果使用C99及更高版本进行编译,则可以使用编译指示运算符:https://gcc.gnu.org/onlinedocs/cpp/Pragmas.html

这是一个小例子:

{{1}}