将OpenMP与-fopenmp和-lgomp链接之间的区别 [英] Difference between linking OpenMP with -fopenmp and -lgomp

查看:1822
本文介绍了将OpenMP与-fopenmp和-lgomp链接之间的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I've been struggling a weird problem the last few days. We create some libraries using GCC 4.8 which link some of their dependencies statically - eg. log4cplus or boost. For these libraries we have created Python bindings using boost-python.

每次这样的库使用TLS(就像log4cplus进行静态初始化时一样,或者stdlibc ++在引发异常时(不仅在初始化阶段时)那样),整个事件都在segfault中崩溃-以及每次线程局部变量的地址已经为0.

Every time such a library used TLS (like log4cplus does in it's static initialization or stdlibc++ does when throwing an exception - not only during initialization phase) the whole thing crashed in a segfault - and every time the address of the thread local variable has been 0.

我尝试了所有操作,例如重新编译,确保使用-fPIC,确保使用-tls-model = global-dynamic等.没有成功.然后,今天我发现这些崩溃的原因是我们链接OpenMP的方式.我们使用"-lgomp"而不是仅使用"-fopenmp"来完成此操作.由于我更改了此设置,所以一切正常-没有崩溃,也没有任何问题.很好!

I tried everything like recompiling, ensuring -fPIC is used, ensuring -tls-model=global-dynamic is used, etc. No success. Then today I found out that the reason for these crashes has been our way of linking OpenMP in. We did this using "-lgomp" instead of just using "-fopenmp". Since I changed this everything works fine - no crashes, no nothing. Fine!

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

But I'd really like to know what the cause of the problem was. So what's the difference between these two possibilities to link in OpenMP?

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

We have a CentOS 5 machine here where we have installed a GCC-4.8 in /opt/local/gcc48 and we are also sure that the libgomp coming from /opt/local/gcc48 had been used as well as the libstdc++ from there (DL_DEBUG used).

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

Any ideas? Haven't found anything on Google - or I used the wrong keywords :)

推荐答案

OpenMP是代码与其执行之间的中介.每个#pragma omp语句都转换为对它们相应的OpenMP库函数的调用,并且所有这些都已存在.多线程执行(启动线程,加入和同步线程等)始终由操作系统(OS)处理. OpenMP所做的全部工作就是在一个简短而优美的界面中轻松地为我们处理这些与底层操作系统相关的线程调用.

OpenMP is an intermediary between your code and its execution. Each #pragma omp statement are converted to calls to their according OpenMP library function, and it's all there is to it. The multithreaded execution (launching threads, joining and synchronizing them, etc.) is always handled by the Operating System (OS). All OpenMP does is handling these low-level OS-dependent threading calls for us portably in a short and sweet interface.

-fopenmp标志是一个高级标志,其作用不仅仅包括GCC的OpenMP实现(gomp).这个gomp库将需要更多的库来访问操作系统的线程功能.在符合POSIX的操作系统上,OpenMP通常基于pthread,需要将其链接.它可能还需要实时扩展库(librt)在某些OS上运行,而在其他OS上则不需要.使用动态链接时,应该自动发现所有内容,但是当您指定-static时,我认为您已经陷入了Jakub Jelinek

The -fopenmp flag is a high-level one that does more than include GCC's OpenMP implementation (gomp). This gomp library will require more libraries to access the threading functionality of the OS. On POSIX-compliant OSes, OpenMP is usually based on pthread, which needs to be linked. It may also need the realtime extension library (librt) to work on some OSes, while not on some other. When using dynamic linking, everything should be discovered automatically, but when you specified -static, I think you've fallen in the situation described by Jakub Jelinek here. But nowadays, pthread (and rt if needed) should be automatically linked when -static is used.

除了链接依赖项之外,-fopenmp标志还激活一些编译指示语句处理.您可以在整个GCC代码中看到(如此处此处)没有-fopenmp标志(仅通过链接gomp库不会触发),多个编译指示将不会转换为适当的OpenMP函数调用.我只是尝试了一些示例代码,并且-lgomp-fopenmp都生成了可工作的可执行文件,该可执行文件链接到相同的库.在我的简单示例中,唯一的区别是-fopenmp具有-lgomp不具有的符号:GOMP_parallel@@GOMP_4.0+(代码

Aside from linking dependencies, the -fopenmp flag also activates some pragma statement processing. You can see throughout the GCC code (as here and here) that without the -fopenmp flag (which isn't trigged by only linking the gomp library), multiple pragmas won't be converted to the appropriate OpenMP function call. I just tried with some example code, and both -lgomp and -fopenmp produce a working executable that links against the same libraries. The only difference in my simple example that the -fopenmp has a symbol that the -lgomp doesn't have: GOMP_parallel@@GOMP_4.0+ (code here) which is the function that initializes the parallel section performing the forks requested by the #pragma omp parallel in my example code. Thus, the -lgomp version did not translate the pragma to a call to GCC's OpenMP implementation. Both produced a working executable, but only the -fopenmp flag produced a parallel executable in this case.

最后,GCC需要-fopenmp来处理所有OpenMP编译指示.如果没有它,您的并行部分将不会派生任何线程,这可能会给内部线程造成严重破坏,具体取决于您执行内部代码的假设.

To wrap up, -fopenmp is needed for GCC to process all the OpenMP pragmas. Without it, your parallel sections won't fork any thread, which could wreak havoc depending on the assumptions on which your inner code was done.

这篇关于将OpenMP与-fopenmp和-lgomp链接之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆