将静态库链接到共享库(例如openmp)是一个好主意

时间:2018-03-22 13:39:07

标签: c++11 openmp static-libraries

我正在linux系统上构建一个共享库,该库旨在用于将部署在服务器上的Docker中的项目中。这个共享库使用openmp。因此,我想知道

是否更好(或更便携)
  1. openmp静态链接到我的共享库
  2. 我应该在Docker中正确安装gcc才能找到openmp
  3. 将openmp的.so与我的库一起分发
  4. 如果选项1是最好的,有人可以用cmake提供正确的方法吗?

    我在下面添加了一些关于这个主题的文档:

2 个答案:

答案 0 :(得分:3)

您通常无法将静态库链接到共享库。

因为静态库(lib*.a)不包含position-independent code(PIC),但共享库需要PIC(实际上)。

(理论上,非PIC共享库是可能的;但是它们会包含很多relocation,“共享”方面会丢失,而dynamic linker会有很多工作所以在实践中,每个共享库都需要是PIC,以允许其code segment [s]在不同的进程中mmap(2)处于不同的地址并保持共享状态

阅读Drepper的How To Write Shared Libraries论文。

但是,您可以将共享库(例如libopenmp.so)链接到另一个(您的共享库,请参阅this)。然后,使用您的共享库的程序将需要libopenmp.so

所以你可以做2或3,甚至将你的库打包为一个正确的.deb包(它将依赖libopenmpi2 Debian包上)。

您可能想了解package management

您应该更了解virtual address spaceprocess。为此,请使用proc(5)pmap(1)。对于第一个示例,请尝试cat /proc/self/mapscat /proc/$$/maps。然后,如果您的流程有pid 1234,请尝试cat /proc/1234/maps和/或pmap 1234。然后,您将了解共享库是如何mmap(2) - 编辑。

答案 1 :(得分:2)

将OpenMP运行时静态链接到另一个共享库是一个坏主意,即使您可以实现它。如果最终代码的某些其他组件也使用OpenMP,那么在此过程中最终会有两个不同的OpenMP运行时。当每个运行时创建自己的线程池并因此性能不佳时,这会快速导致超额预订。 (如果您的代码假定OpenMP关键部分可以保护它免受其他并行代码的影响,那么潜在的正确性失败......)

最简单的答案可能就是您的第3个:使用您的代码发送相关OpenMP运行时共享库​​的副本。