使用 -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 之间的区别 的相关文章

  • BASIC 中的 C 语言中的 PeekInt、PokeInt、Peek、Poke 等效项

    我想知道该命令的等效项是什么Peek and Poke 基本和其他变体 用 C 语言 类似PeekInt PokeInt 整数 涉及内存条的东西 我知道在 C 语言中有很多方法可以做到这一点 我正在尝试将基本程序移植到 C 语言 这只是使用
  • 在 xaml 中编写嵌套类型时出现设计时错误

    我创建了一个用户控件 它接受枚举类型并将该枚举的值分配给该用户控件中的 ComboBox 控件 很简单 我在数据模板中使用此用户控件 当出现嵌套类型时 问题就来了 我使用这个符号来指定 EnumType x Type myNamespace
  • 类型中的属性名称必须是唯一的

    我正在使用 Entity Framework 5 并且有以下实体 public class User public Int32 Id get set public String Username get set public virtual
  • 如何在 C# 中打开 Internet Explorer 属性窗口

    我正在开发一个 Windows 应用程序 我必须向用户提供一种通过打开 IE 设置窗口来更改代理设置的方法 Google Chrome 使用相同的方法 当您尝试更改 Chrome 中的代理设置时 它将打开 Internet Explorer
  • 从经典 ASP 调用 .Net C# DLL 方法

    我正在开发一个经典的 asp 项目 该项目需要将字符串发送到 DLL DLL 会将其序列化并发送到 Zebra 热敏打印机 我已经构建了我的 DLL 并使用它注册了regasm其次是 代码库这使得 IIS 能够识别它 虽然我可以设置我的对象
  • 用于 FTP 的文件系统观察器

    我怎样才能实现FileSystemWatcherFTP 位置 在 C 中 这个想法是 每当 FTP 位置添加任何内容时 我都希望将其复制到我的本地计算机 任何想法都会有所帮助 这是我之前问题的后续使用 NET 进行选择性 FTP 下载 ht
  • C++ 多行字符串原始文字[重复]

    这个问题在这里已经有答案了 我们可以像这样定义一个多行字符串 const char text1 part 1 part 2 part 3 part 4 const char text2 part 1 part 2 part 3 part 4
  • 两个静态变量同名(两个不同的文件),并在任何其他文件中 extern 其中一个

    在一个文件中将变量声明为 static 并在另一个文件中进行 extern 声明 我认为这会在链接时出现错误 因为 extern 变量不会在任何对象中看到 因为在其他文件中声明的变量带有限定符 static 但不知何故 链接器 瑞萨 没有显
  • 两个类可以使用 C++ 互相查看吗?

    所以我有一个 A 类 我想在其中调用一些 B 类函数 所以我包括 b h 但是 在 B 类中 我想调用 A 类函数 如果我包含 a h 它最终会陷入无限循环 对吗 我能做什么呢 仅将成员函数声明放在头文件 h 中 并将成员函数定义放在实现文
  • 为什么 isnormal() 说一个值是正常的,而实际上不是?

    include
  • 如何在 Linq to SQL 中使用distinct 和 group by

    我正在尝试将以下 sql 转换为 Linq 2 SQL select groupId count distinct userId from processroundissueinstance group by groupId 这是我的代码
  • 如何在 Android 中使用 C# 生成的 RSA 公钥?

    我想在无法假定 HTTPS 可用的情况下确保 Android 应用程序和 C ASP NET 服务器之间的消息隐私 我想使用 RSA 来加密 Android 设备首次联系服务器时传输的对称密钥 RSA密钥对已在服务器上生成 私钥保存在服务器
  • 有没有办法让 doxygen 自动处理未记录的 C 代码?

    通常它会忽略未记录的 C 文件 但我想测试 Callgraph 功能 例如 您知道在不更改 C 文件的情况下解决此问题的方法吗 设置变量EXTRACT ALL YES在你的 Doxyfile 中
  • 在 WPF 中使用 ReactiveUI 提供长时间运行命令反馈的正确方法

    我有一个 C WPF NET 4 5 应用程序 用户将用它来打开某些文件 然后 应用程序将经历很多动作 读取文件 通过许多插件和解析器传递它 这些文件可能相当大 gt 100MB 因此这可能需要一段时间 我想让用户了解 UI 中发生的情况
  • C++ 继承的内存布局

    如果我有两个类 一个类继承另一个类 并且子类仅包含函数 那么这两个类的内存布局是否相同 e g class Base int a b c class Derived public Base only functions 我读过编译器无法对数
  • C# 中最小化字符串长度

    我想减少字符串的长度 喜欢 这串 string foo Lorem ipsum dolor sit amet consectetur adipiscing elit Aenean in vehicula nulla Phasellus li
  • 为什么 std::uint32_t 与 uint32_t 不同?

    我对 C 有点陌生 我有一个编码作业 很多文件已经完成 但我注意到 VS2012 似乎有以下语句的问题 typedef std uint32 t identifier 不过 似乎将其更改为 typedef uint32 t identifi
  • C++ 中的参考文献

    我偶尔会在 StackOverflow 上看到代码 询问一些涉及函数的重载歧义 例如 void foo int param 我的问题是 为什么会出现这种情况 或者更确切地说 你什么时候会有 对参考的参考 这与普通的旧参考有何不同 我从未在现
  • Mono 应用程序在非阻塞套接字发送时冻结

    我在 debian 9 上的 mono 下运行一个服务器应用程序 大约有 1000 2000 个客户端连接 并且应用程序经常冻结 CPU 使用率达到 100 我执行 kill QUIT pid 来获取线程堆栈转储 但它总是卡在这个位置
  • 如何确定 CultureInfo 实例是否支持拉丁字符

    是否可以确定是否CultureInfo http msdn microsoft com en us library system globalization cultureinfo aspx我正在使用的实例是否基于拉丁字符集 我相信你可以使

随机推荐