C OpenMP并行for循环不在多个线程上运行

时间:2015-08-20 20:02:28

标签: c multithreading multiprocessing openmp

我正在尝试Open MP的一个简单示例,以并行化for循环,但我看不到for循环正在多个核心上执行。

这是C程序:

#include </usr/local/Cellar/gcc/5.1.0/lib/gcc/5/gcc/x86_64-apple-darwin14.5.0/5.1.0/include/omp.h>
#include <stdio.h>
#include <unistd.h>
int main() {
    int n;
    #pragma omp parallel
    {
        #pragma omp for
        for(n = 0; n < 10; n++)
            printf(" Thread %d: %d\n", omp_get_thread_num(), n);

        printf("Number of threads: %d\n", omp_get_num_threads());
    }
    printf("Total number of cores in the CPU: %ld\n", sysconf(_SC_NPROCESSORS_ONLN));
}

上述代码与this example非常相似。

当我执行这个程序并打印出它使用的线程总数时(默认情况下它应该是CPU核心的总数),我找到了结果1。这是输出:

10:pavithran$ gcc -fopenmp openMPExample.c -o openMPExample.o
10:pavithran$ ./openMPExample.o 
 Thread 0: 0
 Thread 0: 1
 Thread 0: 2
 Thread 0: 3
 Thread 0: 4
 Thread 0: 5
 Thread 0: 6
 Thread 0: 7
 Thread 0: 8
 Thread 0: 9
Number of threads: 1
Total number of cores in the CPU: 8
10:pavithran$ 

为什么我找不到不同线程打印的数字?为什么线程总数总是1?有人请帮助我让并行for循环工作。

PS:第一个“#include ...”语句包含显式路径,因为简单形式为:#include <omp.h> does not seem to work

2 个答案:

答案 0 :(得分:4)

您正在使用不支持OpenMP的Apple铿锵版gcc编译您的程序。这就是你得到输出

的原因
$ gcc main.c -fopenmp
main.c:1:10: fatal error: 'omp.h' file not found
#include <omp.h>
         ^
1 error generated.

使用时

#include <omp.h>

而不是(蒙太奇)

#include </usr/local/Cellar/gcc/5.1.0/lib/gcc/5/gcc/x86_64-apple-darwin14.5.0/5.1.0/include/omp.h>

使用正确版本的gcc

注意: 根据包含路径,我假设使用Homebrew来安装gcc。如果不是这种情况,最后有一节通过Homebrew安装gcc并支持OpenMP。

自制软件将gcc安装为 gcc-4.9 gcc-5 (对于GCC 5.1和GCC 5.2),具体取决于您的版本已安装。 gcc中为/usr/local/bin创建符号链接,因此当您从命令行执行gcc时,您将调用Apple的clang版本。这是我们必须纠正的方法,我们可以通过多种方式使用Homebrew版本的gcc而不是Apple的clang版本

  1. 通过

    明确执行gcc
    $ gcc-5 main.c -fopenmp
    
  2. 使用以下命令在gcc中为/usr/local/bin创建符号链接

    $ cd /usr/local/bin
    $ ln -s gcc-5 gcc
    

    现在,当您执行gcc -v时,您会看到类似于下面的内容(假设您的$PATH变量设置正确,请参见下文,并且您已安装gcc并支持OpenMP通过Homebrew,见下文)

    $ gcc -v
    Using built-in specs.
    COLLECT_GCC=gcc-5
    COLLECT_LTO_WRAPPER=/usr/local/Cellar/gcc/5.2.0/libexec/gcc/x86_64-apple-darwin14.4.0/5.2.0/lto-wrapper
    Target: x86_64-apple-darwin14.4.0
    Configured with: ../configure --build=x86_64-apple-darwin14.4.0 --prefix=/usr/local/Cellar/gcc/5.2.0 --libdir=/usr/local/Cellar/gcc/5.2.0/lib/gcc/5 --enable-languages=c,c++,objc,obj-c++,fortran --program-suffix=-5 --with-gmp=/usr/local/opt/gmp --with-mpfr=/usr/local/opt/mpfr --with-mpc=/usr/local/opt/libmpc --with-isl=/usr/local/opt/isl --with-system-zlib --enable-libstdcxx-time=yes --enable-stage1-checking --enable-checking=release --enable-lto --with-build-config=bootstrap-debug --disable-werror --with-pkgversion='Homebrew gcc 5.2.0 --without-multilib' --with-bugurl=https://github.com/Homebrew/homebrew/issues --enable-plugin --disable-nls --disable-multilib
    Thread model: posix
    gcc version 5.2.0 (Homebrew gcc 5.2.0 --without-multilib)
    
  3. 为自制版gcc创建别名。您可以通过添加类似于

    的行来完成此操作
    alias hgcc='gcc-5'
    

    发送到.bashrc.bash_profile。更好的方法是将其添加到名为.bash_aliases的文件中,然后将其包含在.bashrc.bash_profile

    [[ -f ~/.bash_aliases ]] && . ~/.bash_aliases
    

    然后我们将通过hgcc执行此操作,如

    $ hgcc main.c -fopenmp
    
  4. 除此之外:在OS X上安装带有OpenMP支持的gcc

    要使用OpenMP支持安装gcc,最简单的方法是通过Homebrew。为此,您需要按照one of my previous answers

    使用以下命令
    brew install gcc --without-multilib
    

    或者如果您已经通过Homebrew使用

    安装了gcc
    brew reinstall gcc --without-multilib
    

    这会将gcc安装为 gcc-4.9 gcc-5 (对于GCC 5.1和GCC 5.2),具体取决于您的版本已安装。 gcc中为/usr/local/bin创建符号链接,因此当您从命令行执行gcc时,您将调用Apple的clang版本。您可以通过运行gcc -v来验证这一点,$ gcc -v Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1 Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn) Target: x86_64-apple-darwin14.4.0 Thread model: posix 应该产生类似于下面的输出

    $PATH

    正确设置检查路径

    开启(至少我的Mac系统)默认/usr/local/bin包括/usr/bin之前的$ echo $PATH /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin ,如

    .bashrc

    如果您不是这种情况,则需要修改.bash_profileexport PATH=/usr/local/bin:$PATH 并添加

    gcc

    这可以确保在任何Apple版本之前找到Homebrew版本的gcc-4.9,当我们更正Homebrew将其安装为gcc-5或{{1}}时。

答案 1 :(得分:1)

如何设置OMP_NUM_THREADS环境变量? 什么会给你这样的东西?

 > OMP_NUM_THREADS=8 ./openMPExample.o

(顺便说一句,有一个二进制文件,其名称以&#39; .o&#39;结尾可能不是一个好主意)