C++ 将 OpenMP 与 clang 结合使用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33357029/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using OpenMP with clang
提问by kuhar
I have problems compiling OpenMP code using clang (both 3.6 and 3.8 ToT).
我在使用 clang(3.6 和 3.8 ToT)编译 OpenMP 代码时遇到问题。
I followed this blog post http://blog.llvm.org/2015/05/openmp-support_22.html, but the problem is that the compiled program is executed on a one thread only. I'm using ubuntu 15.04 x64, I have both libgomp and libiopmp installed and I compile my code with the following command:
我关注了这篇博客文章http://blog.llvm.org/2015/05/openmp-support_22.html,但问题是编译的程序仅在一个线程上执行。我使用的是 ubuntu 15.04 x64,我安装了 libgomp 和 libiopmp,我使用以下命令编译我的代码:
clang test.c -o test -fopenmp -L/usr/lib/gcc/x86_64-linux-gnu/5.1.1
When I use gcc instead, everything works fine: gcc test.c -o test -fopenmp
当我改用 gcc 时,一切正常: gcc test.c -o test -fopenmp
I also tried running export LD_LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/5.1.1:$LD_LIBRARY_PATH
but it didn't help.
`
我也试过跑步,export LD_LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/5.1.1:$LD_LIBRARY_PATH
但没有帮助。`
Any suggestions?
有什么建议?
采纳答案by Tim
Update
更新
Building the latest trunk of LLVM/Clang (clang-3.8), installing libiomp5, and specifying the location of the gomp omp header files worked. Note that the Ubuntu package for libiomp5 isn't quite correct, so you will need to add a symlink in /usr/lib from /usr/lib/libiomp5.so to /usr/lib/libiomp5.so.5.
构建最新的 LLVM/Clang 主干 (clang-3.8),安装 libiomp5,并指定 gomp omp 头文件的位置。请注意,用于 libiomp5 的 Ubuntu 包不太正确,因此您需要在 /usr/lib 中添加一个符号链接,从 /usr/lib/libiomp5.so 到 /usr/lib/libiomp5.so.5。
./clang++ -I/usr/lib/gcc/x86_64-linux-gnu/4.9/include -fopenmp=libiomp5 -o test test.cpp
I'm using g++-5.1 and clang++-3.6 on Linux Mint 17.2 (essentially Ubuntu trusty) and I see the same results with the following code.
我在 Linux Mint 17.2(基本上是 Ubuntu 可信赖的)上使用 g++-5.1 和 clang++-3.6,并且我看到以下代码的相同结果。
#include <iostream>
#include <omp.h>
int main() {
#pragma omp parallel num_threads(4)
{
#pragma omp critical
std::cout << "tid = " << omp_get_thread_num() << std::endl;
}
}
Running this under ltrace reveals the issue:
在 ltrace 下运行它揭示了问题:
g++
加++
$ g++ -fopenmp -o test test.cpp
$ ./test
tid = 0
tid = 3
tid = 2
tid = 1
$ ltrace ./test
__libc_start_main(0x400af6, 1, 0x7ffc937b8198, 0x400bc0 <unfinished ...>
_ZNSt8ios_base4InitC1Ev(0x6021b1, 0xffff, 0x7ffc937b81a8, 5) = 0
__cxa_atexit(0x4009f0, 0x6021b1, 0x602090, 0x7ffc937b7f70) = 0
GOMP_parallel(0x400b6d, 0, 4, 0 <unfinished ...>
GOMP_critical_start(0, 128, 0, 0) = 0
tid = 3
tid = 2
omp_get_thread_num(0x7f9fe13894a8, 1, 0, 0x493e0) = 0
_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc(0x6020a0, 0x400c44, 0, 0x493e0) = 0x6020a0
_ZNSolsEi(0x6020a0, 0, 0x7f9fe1a03988, 0x203d2064) = 0x6020a0
_ZNSolsEPFRSoS_E(0x6020a0, 0x400920, 0x7f9fe1a03988, 0 <unfinished ...>
_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_(0x6020a0, 0x400920, 0x7f9fe1a03988, 0) = 0x6020a0
<... _ZNSolsEPFRSoS_E resumed> ) = 0x6020a0
GOMP_critical_end(0x7f9fe0d2d400, 0x7f9fe0d2e9e0, 0, -1) = 0
tid = 1
tid = 0
<... GOMP_parallel resumed> ) = 0
_ZNSt8ios_base4InitD1Ev(0x6021b1, 0, 224, 0x7f9fe0d2df50) = 0x7f9fe1a08940
+++ exited (status 0) +++
clang
铛
$ clang++ -fopenmp -o test test.cpp
$ ./test
tid = 0
$ ltrace ./test
__libc_start_main(0x4009a0, 1, 0x7ffde4782538, 0x400a00 <unfinished ...>
_ZNSt8ios_base4InitC1Ev(0x6013f4, 0x7ffde4782538, 0x7ffde4782548, 5) = 0
__cxa_atexit(0x400830, 0x6013f4, 0x6012c8, 0x7ffde4782310) = 0
_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc(0x6012e0, 0x400a84, 0x7ffde4782548, 6) = 0x6012e0
omp_get_thread_num(0x7f3e4698c006, 0x7f3e4698c000, 0x7f3e46764988, 1024) = 0
_ZNSolsEi(0x6012e0, 0, 0x7f3e46764988, 1024) = 0x6012e0
_ZNSolsEPFRSoS_E(0x6012e0, 0x4007a0, 0x7f3e46764988, 0 <unfinished ...>
_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_(0x6012e0, 0x4007a0, 0x7f3e46764988, 0) = 0x6012e0
tid = 0
<... _ZNSolsEPFRSoS_E resumed> ) = 0x6012e0
_ZNSt8ios_base4InitD1Ev(0x6013f4, 0, 224, 0x7f3e45886f50) = 0x7f3e46769940
+++ exited (status 0) +++
You can immediately see the problem: clang++ never calls GOMP_parallel, so you always get one thread. This is crazy behavior on the part of clang. Have you tried building and using the "special" OpenMP versionof clang?
您可以立即看到问题:clang++ 从不调用 GOMP_parallel,因此您总是得到一个线程。这是 clang 的疯狂行为。您是否尝试过构建和使用“特殊” OpenMP 版本的 clang?
回答by Andrey Bokhanko
Some additional comments:
一些补充意见:
1) You need to use -fopenmp=libomp to enable OpenMP in clang. -fopenmp just links libgomp but ignores all the pragmas. Weird, I know -- and will be changed in the trunk soon.
1) 您需要使用 -fopenmp=libomp 在 clang 中启用 OpenMP。-fopenmp 只是链接 libgomp 但忽略所有编译指示。很奇怪,我知道——很快就会在后备箱里换掉。
2) 3.7 is the first version that supports OpenMP. 3.6 doesn't.
2) 3.7 是第一个支持 OpenMP 的版本。3.6 没有。
3) clang is only able to work with libomp. Don't put libgomp (headers or the library) in the way of libomp! clang uses Intel API, not supported by libgomp. -fopenmp=libomp should link correct library.
3) clang 只能与 libomp 一起工作。不要将 libgomp(头文件或库)放在 libomp 的方式中!clang 使用 Intel API,libgomp 不支持。-fopenmp=libomp 应该链接正确的库。
回答by veio
I made it work on Linux Mint 17.2. (essentially Ubuntu 14.04) with:
我让它在 Linux Mint 17.2 上运行。(本质上是 Ubuntu 14.04):
packages: libiomp-dev clang-3.8
软件包:libiomp-dev clang-3.8
Compile flag: -fopenmp
编译标志: -fopenmp
Linker flag: -fopenmp=libiomp5
链接器标志: -fopenmp=libiomp5
Now it compiles and uses multiple threads.
现在它编译并使用多个线程。
Here is the modified FindOpenMP.cmake
这是修改后的FindOpenMP.cmake
回答by Hyman Wasey
OMP_NUM_THREADS environment variable is probably what you want. You can also set it programmatically.
OMP_NUM_THREADS 环境变量可能就是你想要的。您也可以以编程方式设置它。
https://gcc.gnu.org/onlinedocs/libgomp/Environment-Variables.html
https://gcc.gnu.org/onlinedocs/libgomp/Environment-Variables.html
And same for clang.
和叮当一样。