C 有没有干净的方法让OpenMP pragmas与宏一起工作?

C 有没有干净的方法让OpenMP pragmas与宏一起工作?,c,c++11,macros,openmp,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 oth

我必须将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
}
。。。因为如果MAC1和/或MAC2未定义,编译器会抱怨x1、y1和/或x2、y2未定义

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

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

2我想我可以把这些变量从它们的宏块中拉出来,并定义它们是否需要。这将是最简单的解决方案,但这似乎有点像黑客。我怀疑在原则上,有些情况下,这无论如何都是行不通的

3我想我可以编写几个omp pragma,每个宏组合一个,封装在四个不同的ifdef中,但是我需要四个不同的可选pragma,代码很快就会变得一团糟

我试着做一些类似的事情

#pragma omp parallel private(the other stuff) \
#ifdef MAC1
                     private(x1, y1)   \
#endif
#ifdef MAC2
                     private(x2, y2)   \
#endif
{ ... }
这看起来仍然不太好,但它比四个不同的可选pragma要好得多。尽管如此,我尝试了几种不同的语法,但编译器不知道我在做什么


有谁知道一个干净的方法来做我想做的事情吗?

我能想到的最简单、最自然的方法是:

// 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_变量和MAC2_变量可以适当地展开,要么不展开,要么展开到变量列表的适当子序列


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

如果您使用C99及以上版本编译,您可以使用pragma操作符:

下面是一个小的工作示例:

#include <stdio.h>
#include <omp.h>

#define MAC1
#define MAC2

#ifdef MAC1
double x1 = 0.0, y1 = 0.1;
#endif

#ifdef MAC2
double x2 = 1.0, y2 = 1.1;
#endif

#if defined(MAC1) && defined(MAC2)
# define MY_OMP_LOOP_PRAGMA _Pragma("omp parallel for firstprivate(x1, y1, x2, y2)")
#elif defined(MAC1)
# define MY_OMP_LOOP_PRAGMA _Pragma("omp parallel for firstprivate(x1, y1)")
#elif defined(MAC2)
# define MY_OMP_LOOP_PRAGMA _Pragma("omp parallel for firstprivate(x2, y2)")
#endif

int main(int argc, char* argv[])
{
   int imax = 10;
MY_OMP_LOOP_PRAGMA
   for (int i=0; i < imax; ++i) {
#ifdef MAC1
     printf("%d: %f, %f\n", omp_get_thread_num(), x1, y1);
#endif
#ifdef MAC2
    printf("%d: %f, %f\n", omp_get_thread_num(), x2, y2);
#endif
}

  return 0;
}

您能定义macx和macy并在函数调用中使用它们吗?@WeatherVane非常感谢您的帮助。我不知道你的意思。可能是因为我在这方面是新手。你能详细说明一下吗?非常感谢!如答案中所述。有趣。我以前从未见过这种情况。谢谢
#include <stdio.h>
#include <omp.h>

#define MAC1
#define MAC2

#ifdef MAC1
double x1 = 0.0, y1 = 0.1;
#endif

#ifdef MAC2
double x2 = 1.0, y2 = 1.1;
#endif

#if defined(MAC1) && defined(MAC2)
# define MY_OMP_LOOP_PRAGMA _Pragma("omp parallel for firstprivate(x1, y1, x2, y2)")
#elif defined(MAC1)
# define MY_OMP_LOOP_PRAGMA _Pragma("omp parallel for firstprivate(x1, y1)")
#elif defined(MAC2)
# define MY_OMP_LOOP_PRAGMA _Pragma("omp parallel for firstprivate(x2, y2)")
#endif

int main(int argc, char* argv[])
{
   int imax = 10;
MY_OMP_LOOP_PRAGMA
   for (int i=0; i < imax; ++i) {
#ifdef MAC1
     printf("%d: %f, %f\n", omp_get_thread_num(), x1, y1);
#endif
#ifdef MAC2
    printf("%d: %f, %f\n", omp_get_thread_num(), x2, y2);
#endif
}

  return 0;
}