gcc - 告诉 GCC *not* 链接 libgomp 所以它链接 libiomp5

标签 gcc openmp intel-mkl libgomp

我需要找出一个可以输入 gcc 的编译器/链接器指令,以便在指定 -fopenmp 时它不会自动链接 libgomp。

原因是我正在尝试针对英特尔的 MKL BLAS 进行构建。 MKL 需要添加一个单独的英特尔库来处理多线程(例如,libmkl_intel_thread 或 libmkl_gnu_thread)。然而,用于将 MKL 与 libgomp 链接的库并非在每个操作系统上都可用,包括我的操作系统。这迫使我链接 libmkl_intel_thread,而后者又必须链接到 libiomp5。

虽然我能够构建我的包,但一些二进制文件同时与 libgomp 和 libiomp5 链接。我不肯定这会导致问题,但是已经发生了一些崩溃,链接组合是可疑的,即使它没有导致崩溃,它肯定是一个可怕的低效率。

我正在尝试使用 gcc 4.9.1 来做到这一点。

不幸的是,避免 -fopenmp 不是一种选择。原因是这是为了编译一个由几个子包组成的相当大的包,它们的 Makefile 不是最大的形状,并且以后可能会编译来自其他源(插件)的附加包。强制使用通用编译器/链接器指令并不困难。但是,打开 --enable-openmp 会同时激活 -fopenmp,并定义用于触发与多线程相关的代码。试图将这三个(--enable-openmp、-fopenmp 和链接到--enable-openmp 的代码)分开是不可行的。

我浏览了手册页,但没有看到任何允许选择 openmp 库的 gcc 指令。英特尔的论坛有一个非常古老的讨论,他们建议在 -fopenmp 之后立即指定一个静态库,然后是 --as-needed。这看起来相当摇摇晃晃,并且也有很大的潜力干扰插件包。 llvm-openmp 似乎曾经考虑过 -fopenmp=libiomp5 指令,但它似乎已在 3.5 版本中被删除,而且我无论如何都在尝试使用 gcc。

谢谢。

最佳答案

我想我现在有一个答案;我和英特尔的人有过几次交流,我想分享一下结果。这是他们的一些建议和我自己想出的混合:

  • 简短的回答是,你不能。 Gcc 希望在链接器阶段强制使用 libgomp。如果 libiomp 也被链接,那么这两个库都将被链接。会叫哪一个?我不知道。
  • 更长的答案是,在某些发行版上,可以通过创建自定义 libgomp.spec 或更改与 gcc 一起安装的 libgomp.spec 来更改 gcc 的默认行为(每当设置 -fopenmp 时添加 libgomp)。在我的发行版(自制软件)上,这是不可行的; “libgomp.spec”文件是空的,libgomp 的规范是 gcc 内置的。所有这些都必须被覆盖。每当 gcc 更新时,这都必须重做。
  • 在某些操作系统上,可以将每个副本和指向 libgomp 的链接替换为指向 libiomp5 的符号链接(symbolic link)。然后二进制文件将有多个链接指向同一个库,但有两个不同的名称。那时会发生什么?我不知道。
  • 我最终做的是从 gcc 转移到 llvm 的 clang-omp 实现。除非另有说明,否则它使用 libiomp5。我对此的担忧是我项目的一部分使用了 fortran,并且没有 llvm fortran 编译器。但事实证明,即使将 -fopenmp 提供给 gfortran,只要 llvm 最终进行链接,它就会清除对 libgomp 的任何引用并用 libiomp5 替换它们。 clang-omp 也可以选择使用 -fopenmp=[libiomp5|libgomp] 选择 omp 库,但我无法使其始终如一地工作。无论如何,llvm 3.5 的 clang-omp 实现几乎涵盖了所有的 openmp 规范,到目前为止,似乎没有任何东西在 switch 中丢失。事实上性能有所提高。
  • 为了记录,我确实尝试使用 gfortran 作为使用 dragonegg 的 llvm 前端。这本书得不偿失。 Dragonegg 与 gcc 4.9 不兼容,因此它强制使用 gcc 4.8。很难设置;随着版本的变化,似乎很难维护; llvm 的人不确定 Dragonegg 的前进会有多少支持;并且在所有事件中,性能都不如仅使用 llvm。
  • 驱使我来到这里的问题是如何获得一个包含 C 和 fortran 组件的包,它使用 OpenMP,针对 MKL 编译,我的操作系统的 MKL 库与 iomp5 硬链接(hard link),并且不接受 gomp。答案是唯一可行的选择是从 gcc 迁移到 clang-omp。
  • 正如 OpenMP 网站上所声称的那样,这确实留下了“iomp5 是否与 gcc 4.9 兼容”的问题。答案很简单,“不”,iomp5 和 gcc 4.9 将无法相互协作 --- 至少无需对工具链进行实质性修改,没有可用的指导或文档,而且尚不清楚是否有人这样做成功地。
  • 关于gcc - 告诉 GCC *not* 链接 libgomp 所以它链接 libiomp5,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25986091/

    相关文章:

    python - 在 python 的 C 扩展中包含外部共享英特尔的 mkl 库

    在 Mac 上编译 Unix 代码

    c++ - 为什么 QCustomPlot 在绘制大数据时速度太慢?

    c - 使用 OpenMP 和 OpenSSL 时的内存泄漏和段错误

    intel - 将 Intel MKL double 组与 MKL_Complex16 数组(和 exp)相乘?

    c++ - mxnet 使用 intel mkl 构建总是抛出错误 "Intel MKL FATAL ERROR: Cannot load mkl_intel_thread.dll."

    c++ - 我可以升级 Xcode 以支持更新版本的 GCC 来学习 C++0x 吗?

    c++ - 不一致的警告 "conversion from ' const unsigned char' to 'const float' requires a narrowing conversion”

    c - for 循环上的多个 pragma 指令(C 和 VS 2013)

    c - 循环中缺少错误(OpenMP with C)