使用 -fopenmp 和 -lgomp 链接 OpenMP 之间的区别

2024-04-11

最近几天我一直在努力解决一个奇怪的问题。我们使用 GCC 4.8 创建一些库,静态链接它们的一些依赖项 - 例如。 log4cplus 或 boost。对于这些库,我们使用 boost-python 创建了 Python 绑定。

每次这样的库使用 TLS(就像 log4cplus 在静态初始化中所做的那样,或者 stdlibc++ 在抛出异常时所做的那样 - 不仅在初始化阶段),整个事情都会在段错误中崩溃 - 并且每次线程局部变量的地址为 0 。

我尝试了各种方法,例如重新编译、确保使用 -fPIC、确保使用 -tls-model=global-dynamic 等,但没有成功。今天我发现这些崩溃的原因是我们链接 OpenMP 的方式。我们使用“-lgomp”而不是仅使用“-fopenmp”来完成此操作。自从我改变了这个之后,一切都工作正常 - 没有崩溃,没有什么。美好的!

但我真的很想知道问题的原因是什么。那么这两种在 OpenMP 中链接的可能性有什么区别呢?

我们这里有一台 CentOS 5 机器,我们在 /opt/local/gcc48 中安装了 GCC-4.8,并且我们还确信来自 /opt/local/gcc48 的 libgomp 以及来自那里的 libstdc++ (DL_DEBUG用过的)。

有任何想法吗?在 Google 上没有找到任何内容 - 或者我使用了错误的关键字:)


OpenMP 是代码与其执行之间的中介。每个#pragma omp语句被转换为对其相应 OpenMP 库函数的调用,仅此而已。多线程执行(启动线程、连接和同步线程等)始终由操作系统 (OS) 处理。 OpenMP 所做的就是在一个简短而友好的界面中为我们处理这些低级的依赖于操作系统的线程调用。

The -fopenmpflag 是一个高级标志,它不仅仅包括 GCC 的 OpenMP 实现 (gomp)。该 gomp 库将需要更多库来访问操作系统的线程功能。在兼容 POSIX 的操作系统上,OpenMP 通常基于 pthread,需要链接。它还可能需要实时扩展库 (librt) 才能在某些操作系统上运行,而在其他操作系统上则不行。使用动态链接时,所有内容都应该自动发现,但是当您指定-static,我认为你已经陷入了 Jakub Jelinek 所描述的情况here https://gcc.gnu.org/bugzilla/show_bug.cgi?id=24845。但如今,pthread(如果需要的话还有 rt)应该在以下情况下自动链接:-static用来。

除了链接依赖项之外,-fopenmpflag 还激活一些 pragma 语句处理。您可以看到整个 GCC 代码(如here https://github.com/gcc-mirror/gcc/blob/2cc80ac37074949b269d06bd7b3b8e61932eb0be/gcc/omp-low.c#L8851 and here https://github.com/gcc-mirror/gcc/blob/2cc80ac37074949b269d06bd7b3b8e61932eb0be/gcc/omp-low.c#L10751),如果没有-fopenmp标志(仅通过链接 gomp 库不会触发),多个编译指示将不会转换为适当的 OpenMP 函数调用。我只是尝试了一些示例代码,并且都-lgomp and -fopenmp生成一个链接到相同库的工作可执行文件。我的简单示例中唯一的区别是-fopenmp有一个符号表示-lgomp没有:GOMP_parallel@@GOMP_4.0+ (code here https://github.com/gcc-mirror/gcc/blob/3ba965c0a3571219c638da1ba3ce64ed6623556e/libgomp/parallel.c#L163)这是初始化并行部分的函数,该并行部分执行所请求的分叉#pragma omp parallel在我的示例代码中。就这样-lgomp版本没有将编译指示转换为对 GCC 的 OpenMP 实现的调用。两者都生成了一个工作可执行文件,但仅-fopenmp在这种情况下,flag 生成了一个并行可执行文件。

总结一下,-fopenmpGCC 需要处理所有 OpenMP 编译指示。如果没有它,您的并行部分将不会分叉任何线程,这可能会造成严重破坏,具体取决于完成内部代码的假设。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 -fopenmp 和 -lgomp 链接 OpenMP 之间的区别 的相关文章

随机推荐