34

我有一个使用 OpenMP 的 C++ 程序,它将在可能安装或未安装 OpenMP 的几台机器上运行。

我怎样才能让我的程序知道机器是否没有 OpenMP 并忽略那些#include <omp.h>OpenMP 指令(如#pragma omp parallel ...)和/或库函数(如tid = omp_get_thread_num();)?

4

5 回答 5

68

OpenMP 编译添加了预处理器定义“_OPENMP”,因此您可以:

#if defined(_OPENMP)
   #pragma omp ...
#endif

有关一些示例,请参阅http://bisqwit.iki.fi/story/howto/openmp/#Discussion和以下代码。

于 2011-12-09T14:36:33.200 回答
25

编译器应该忽略#pragma他们不理解的指令;这就是语法的重点。中定义的函数在openmp.h非并行系统上具有简单的定义明确的含义——特别是,头文件将检查编译器是否定义ENABLE_OPENMP,如果未启用,则提供正确的回退。

因此,您只需要一份openmp.h链接即可。这是一个:http ://cms.mcc.uiuc.edu/qmcdev/docs/html/OpenMP_8h-source.html 。

但是,代码的相关部分就是这样:

#if defined(ENABLE_OPENMP)
#include <omp.h>
#else
typedef int omp_int_t;
inline omp_int_t omp_get_thread_num() { return 0;}
inline omp_int_t omp_get_max_threads() { return 1;}
#endif

在最坏的情况下,您可以只取这三行并将它们放在一个虚拟openmp.h文件中,然后使用它。其余的将正常工作。

于 2010-03-02T10:28:02.217 回答
0

OpenMP 是编译器运行时的东西,而不是平台的东西。

IE。如果您使用 Visual Studio 2005 或更高版本编译您的应用程序,那么您始终可以使用 OpenMP,因为运行时支持它。(如果最终用户没有安装 Visual Studio C 运行时,那么您的应用程序将根本无法运行)。

所以,你不用担心,如果你能用它,它就会像strcmp这样的函数一样一直存在。为确保他们拥有 CRT,您可以安装 Visual Studio Redistributable。

编辑:

好的,但是 GCC 4.1 将无法编译您的 openMP 应用程序,所以问题不是目标机器,而是目标编译器。由于所有编译器都有提供其版本的预定义宏,因此请使用 #ifdef 块包装您的 OpenMP 调用。例如,GCC 使用 3 个宏来识别编译器版本,__GNUC__, __GNUC_MINOR__ and __GNUC_PATCHLEVEL__

于 2009-08-19T14:12:46.253 回答
0

我怎样才能让我的程序知道机器是否没有 OpenMP 并忽略那些#include <omp.h>OpenMP 指令(如#pragma omp parallel ...)和/或库函数(如tid = omp_get_thread_num();)?

这是一个迟到的答案,但由于在 Microsoft 编译器上使用,我们刚刚收到了一个错误报告。#pragma omp simd

根据OpenMP 规范,第 2.2 节:

条件编译

在支持预处理器的实现中,_OPENMP 宏名称被定义为具有十进制值 yyyymm,其中 yyyy 和 mm 是实现支持的 OpenMP API 版本的年份和第一个名称。

似乎现代 Microsoft 编译器仅在 2000 年至 2005 年之间的某个时间支持 OpenMP。我只能说“介于两者之间”,因为 OpenMP 2.0 于 2000 年发布,而 OpenMP 2.5 于 2005 年发布。但微软宣传了 2002 年的版本。

这里有一些_OPENMP数字...

  • 视觉工作室 2012 - OpenMP 200203
  • 视觉工作室 2017 - OpenMP 200203
  • IBM XLC 13.01 - OpenMP 201107
  • 铿锵声 7.0 - OpenMP 201107
  • GCC 4.8 - OpenMP 201107
  • GCC 8.2 - OpenMP 201511

因此,如果您想使用,比如说#pragma omp simd保护一个循环,并且#pragma omp simd在 OpenMP 4.0 中可用,那么:

#if _OPENMP >= 201307
    #pragma omp simd
    for (size_t i = 0; i < 16; ++i)
        data[i] += x[i];
#else
    for (size_t i = 0; i < 16; ++i)
        data[i] += x[i];
#endif

它将在可能安装或未安装 OpenMP 的几台机器上运行。

需要明确的是,您可能需要在每台机器上构建您的程序。x86_64 ABI不保证 OpenMP 在 x86、x32 或 x86_64 机器上可用。而且我还没有读过你可以在一台机器上构建,然后在另一台机器上运行。

于 2019-01-22T09:12:28.617 回答
-1

我喜欢另一种方法,从Bisqwit借来的:

#if defined(_OPENMP)
#include <omp.h>
extern const bool parallelism_enabled = true;
#else
extern const bool parallelism_enabled = false;
#endif

然后,像这样启动 OpenMP 并行 for 循环:

#pragma omp parallel for if(parallelism_enabled)

注意:有不使用的正当理由pragma,这是非标准的,因此谷歌和其他人不支持它。

于 2018-06-14T01:05:13.947 回答