将OpenMP与clang一起使用

我在使用clang(3.6和3.8 ToT)编译OpenMP代码时遇到问题。

我关注了这篇博文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 

当我使用gcc时,一切正常: gcc test.c -o test -fopenmp

我也试过运行export LD_LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/5.1.1:$LD_LIBRARY_PATH但它没有帮助。 `

有什么建议?

更新

构建最新的LLVM / Clang主干(clang-3.8),安装libiomp5,并指定gomp omp头文件的位置。 请注意,libiomp5的Ubuntu包不太正确,因此您需要在/usr/lib/libiomp5.so中将/ usr / lib中的符号链接添加到/usr/lib/libiomp5.so.5。

 ./clang++ -I/usr/lib/gcc/x86_64-linux-gnu/4.9/include -fopenmp=libiomp5 -o test test.cpp 

我在Linux Mint 17.2(基本上是Ubuntu可信任)上使用g ++ – 5.1和clang ++ – 3.6,我看到了与以下代码相同的结果。

 #include  #include  int main() { #pragma omp parallel num_threads(4) { #pragma omp critical std::cout << "tid = " << omp_get_thread_num() << std::endl; } } 

在ltrace下运行它会显示问题:

克++

 $ g++ -fopenmp -o test test.cpp $ ./test tid = 0 tid = 3 tid = 2 tid = 1 $ ltrace ./test __libc_start_main(0x400af6, 1, 0x7ffc937b8198, 0x400bc0  _ZNSt8ios_base4InitC1Ev(0x6021b1, 0xffff, 0x7ffc937b81a8, 5) = 0 __cxa_atexit(0x4009f0, 0x6021b1, 0x602090, 0x7ffc937b7f70) = 0 GOMP_parallel(0x400b6d, 0, 4, 0  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  _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++ -fopenmp -o test test.cpp $ ./test tid = 0 $ ltrace ./test __libc_start_main(0x4009a0, 1, 0x7ffde4782538, 0x400a00  _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  _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) +++ 

你可以立即看到问题:clang ++从不调用GOMP_parallel,所以你总是得到一个线程。 这是铿锵声的疯狂行为。 您是否尝试过构建和使用“特殊” OpenMP版本的clang?

一些额外的评论:

1)您需要使用-fopenmp = libomp在clang中启用OpenMP。 -fopenmp只链接libgomp但忽略了所有的pragma。 很奇怪,我知道 – 并且很快就会在行李箱中更换。

2)3.7是第一个支持OpenMP的版本。 3.6没有。

3)clang只能使用libomp。 不要把libgomp(头文件或库)放在libomp的方式! clang使用Intel API,libgomp不支持。 -fopenmp = libomp应链接正确的库。

此致,

安德烈·博汉科

软件工程师Intel

我在Linux Mint 17.2上工作了。 (基本上是Ubuntu 14.04):

包:libiomp-dev clang-3.8

编译标志: -fopenmp

链接器标志: -fopenmp=libiomp5

现在它编译并使用多个线程。

这是修改后的FindOpenMP.cmake

OMP_NUM_THREADS环境变量可能就是您想要的。 您也可以通过编程方式进行设置。

https://gcc.gnu.org/onlinedocs/libgomp/Environment-Variables.html

同样的铿锵声。