【问题标题】:Check in preprocessor that g++ is called with -fopenmp检查使用 -fopenmp 调用 g++ 的预处理器
【发布时间】:2023-04-07 14:37:01
【问题描述】:

我的代码使用 OpenMP,我使用 g++ 构建它,如下所示:

g++ -std=c++17 -O3 -fopenmp main.cpp -o helloworld

现在,出于调试和测试目的,我有时想在没有 OpenMP 的情况下使用类似的东西构建代码:

g++ -std=c++17 -O3 main.cpp -o helloworld

由于未链接 OpenMP 函数(未使用-fopenmp),因此无法构建代码。所以我的想法是使用一些预处理器魔法,比如:

#ifdef OPENMP
// run OpenMP-specific code
#else
// run this code only if -fopenmp was not set
#endif

这可能吗?问题可能是-fopenmp 仅用于链接 OpenMP 库,因此在构建的预处理器阶段可能不知道/不使用。

【问题讨论】:

  • g++ -DOPENMP -fopenmp ?
  • hmmm 这很简单,肯定会工作 :) 我现在会使用它,但如果可以避免这种冗余,仍然很有趣。我只是担心我很容易忘记并使用-fopenmp 而没有-DOPENMP :)
  • 另外,如果我忘记添加-DOPENMP,在构建过程中不会出错(预处理器只会跳转到#else 部分)

标签: c++ g++ c-preprocessor openmp


【解决方案1】:

OpenMP 标准提出了一个专门用于这种情况的宏:_OPENMP

当且仅当编译代码并激活对 OpenMP 的支持时,才会定义此宏。此外,虽然这不是您的问题,但定义宏以反映编译器支持的标准版本。

更准确地说,宏在设置时使用以下格式定义: YYYYMM 其中YYYY 表示年份,MM 表示采用支持的标准的月份。由于该标准定期合并新闻功能,这允许通过检查 _OPENMP 是否大于或等于所需的最小值来检查代码是否支持所需的功能。

最后,请注意,您可能还需要考虑以下替代方案来解决您的问题。事实上,如果出于调试原因,您不希望在激活 OpenMP 的情况下编译您的代码,但即使它调用 OpenMP 特定函数(如 omp_get_num_threads()),您仍然希望它工作,您可以替换 -fopenmp 随处切换 -lgomp。使用这个简单的技巧不会启用您的 OpenMP 指令,但您仍将链接定义您需要的函数的 OpenMP 运行时。 Ans 由于调用它们时您不会处于任何活动的并行区域中,因此它们将完全按照您希望它们执行的操作。

【讨论】:

  • 我尝试使用g++ -std=c++17 -O3 -lgomp main.cpp -o helloworld 编译我的代码并得到错误:/usr/bin/ld: /tmp/cczRLSJu.o: in function `main': main.cpp:(.text.startup+0x256): undefined reference to `omp_get_num_threads' /usr/bin/ld: main.cpp:(.text.startup+0x161e): undefined reference to `omp_get_thread_num' collect2: error: ld returned 1 exit status
  • 糟糕。对。我忘记了这里的顺序很重要。 -lgomp 必须在 main.cpp 之后,因为链接器从左到右解析对象中的依赖关系。所以在 main.cpp 之前不需要 OpenMP 对象。因此它实际上并没有链接 libgomp。在 main.cpp 之后,就无法再访问 libgomp 了。因此,只需尝试更改顺序即可。
猜你喜欢
  • 2015-08-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多