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

Pav*_*yer 2 c multithreading openmp multiprocessing

我正在尝试一个简单的 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));
}
Run Code Online (Sandbox Code Playgroud)

上面的代码与这个例子非常相似。

当我执行这个程序并打印出它正在使用的线程总数(默认情况下它应该是 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$ 
Run Code Online (Sandbox Code Playgroud)

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

PS:第一个“#include ...”语句包含显式路径,因为简单的形式:#include <omp.h> 似乎不起作用

IKa*_*agh 5

您正在使用gcc不支持 OpenMP 的Apple 的 clang 版本编译您的程序。这就是为什么你得到输出

$ gcc main.c -fopenmp
main.c:1:10: fatal error: 'omp.h' file not found
#include <omp.h>
         ^
1 error generated.
Run Code Online (Sandbox Code Playgroud)

使用时

#include <omp.h>
Run Code Online (Sandbox Code Playgroud)

相对于(montrosity)

#include </usr/local/Cellar/gcc/5.1.0/lib/gcc/5/gcc/x86_64-apple-darwin14.5.0/5.1.0/include/omp.h>
Run Code Online (Sandbox Code Playgroud)

使用正确的版本 gcc

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

Homebrew 安装gccgcc-4.9gcc-5(对于 GCC 5.1 和 GCC 5.2)取决于您安装的版本。它并没有为创建符号链接gcc/usr/local/bin,所以当你执行gcc从您将调用苹果铛版本的命令行。这是我们必须纠正的问题,我们可以通过多种方式使用gccApple 的 clang 版本的 Homebrew版本

  1. gcc通过显式执行

    $ gcc-5 main.c -fopenmp
    
    Run Code Online (Sandbox Code Playgroud)
  2. 使用以下命令为gccin创建符号链接/usr/local/bin

    $ cd /usr/local/bin
    $ ln -s gcc-5 gcc
    
    Run Code Online (Sandbox Code Playgroud)

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

    $ 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)
    
    Run Code Online (Sandbox Code Playgroud)
  3. 为 Homebrew 版本创建别名gcc。您可以通过添加类似于

    alias hgcc='gcc-5'
    
    Run Code Online (Sandbox Code Playgroud)

    到您的.bashrc.bash_profile。什么是更好的是将其添加到一个名为.bash_aliases然后包括在您.bashrc.bash_profile

    [[ -f ~/.bash_aliases ]] && . ~/.bash_aliases
    
    Run Code Online (Sandbox Code Playgroud)

    然后我们将通过hgcc如下方式执行它

    $ hgcc main.c -fopenmp
    
    Run Code Online (Sandbox Code Playgroud)

旁白:gcc在 OS X 上安装OpenMP 支持

要安装gccOpenMP 支持,最简单的方法是通过Homebrew。为此,您需要按照我之前的答案之一使用以下命令

brew install gcc --without-multilib
Run Code Online (Sandbox Code Playgroud)

或者如果您已经gcc通过 Homebrew安装,请使用

brew reinstall gcc --without-multilib
Run Code Online (Sandbox Code Playgroud)

这将根据您安装的版本安装gccgcc-4.9gcc-5(对于 GCC 5.1 和 GCC 5.2)。它并没有为创建符号链接gcc/usr/local/bin,所以当你执行gcc从您将调用苹果铛版本的命令行。您可以通过运行来验证这一点,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
Run Code Online (Sandbox Code Playgroud)

检查路径设置是否正确

在(至少我的 Mac 系统)上,默认$PATH包括/usr/local/bin之前/usr/bin

$ echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
Run Code Online (Sandbox Code Playgroud)

如果您不是这种情况,则需要编辑.bashrc.bash_profile添加

export PATH=/usr/local/bin:$PATH
Run Code Online (Sandbox Code Playgroud)

这确保了 Homebrew 版本gcc将在任何 Apple 版本之前找到,当我们更正 Homebrew 将其安装为gcc-4.9或 时gcc-5