简体   繁体   English

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

[英]C OpenMP parallel for loop is not running on more than one thread

I am trying a simple example of Open MP, to parallelize a for loop, but I cannot see that the for loop is being executed on more than one core. 我正在尝试一个简单的Open MP示例来并行化for循环,但是我看不到for循环正在多个内核上执行。

Here is the C program: 这是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));
}

The above code is very similar to this example . 上面的代码与此示例非常相似。

When I execute this program and print out the total number of threads being used by it (by default it should be the total number of CPU cores), I find the result 1 . 当我执行该程序并打印出它正在使用的线程总数(默认情况下,它应该是CPU内核的总数)时,我发现结果1 Here is the output: 这是输出:

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$ 

Why is it that I do not find the numbers being printed by different threads? 为什么找不到不同线程打印的数字? Why is it that the total number of threads is always 1? 为什么线程总数总是1? Someone please help me in getting the parallel for loop to work. 有人请帮助我使并行for循环工作。

PS: The first "#include ..." statement contains the explicit path because the simple form: #include <omp.h> does not seem to work . PS:第一个“ #include ...”语句包含显式路径,因为简单形式: #include <omp.h> 似乎不起作用

You are compiling your program with Apple's clang version of gcc that does not support OpenMP. 您正在使用不支持OpenMP的Apple的gcc clang版本编译程序。 This is why you get the output 这就是为什么你得到输出

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

when using 使用时

#include <omp.h>

as opposed to (the 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>

Using the Correct Version of gcc 使用正确版本的gcc

Note: Based on the include path I'm assuming use of Homebrew to install gcc . 注意: 基于包含路径,我假设使用Homebrew安装gcc If that is not the case there is a section at the end on installing gcc via Homebrew with OpenMP support. 如果不是这种情况,那么最后一节将介绍如何通过具有OpenMP支持的Homebrew安装gcc

Homebrew installs gcc as gcc-4.9 or gcc-5 (for both GCC 5.1 and GCC 5.2) depending on the version you have installed. 根据所安装的版本,Homebrew将gcc安装为gcc-4.9gcc-5 (对于GCC 5.1和GCC 5.2)。 It does not create a symlink for gcc in /usr/local/bin and so when you execute gcc from the command line you will be calling Apple's clang version. 不会创建符号链接gcc/usr/local/bin ,当你执行等gcc从您将调用苹果铛版本的命令行。 This is what we must correct for and there are a multitude of ways in which we can use the Homebrew version of gcc over Apple's clang version 这是我们必须纠正的问题,我们可以通过多种方式使用gcc的Homebrew版本而不是Apple的clang版本。

  1. Explicitly execute gcc via 通过显式执行gcc

     $ gcc-5 main.c -fopenmp 
  2. Create a symlink for gcc in /usr/local/bin with the following commands 使用以下命令在/usr/local/bingcc创建符号链接

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

    Now when you execute gcc -v you should see something similar to the below (providing your $PATH variable is set up correctly, see below, and you've installed gcc with OpenMP support via Homebrew, see below) 现在,当您执行gcc -v您应该会看到类似于以下内容(假设$PATH变量设置正确,请参见下文,并且已经通过Homebrew安装了具有OpenMP支持的gcc ,请参见下文)

     $ 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. Create an alias for the Homebrew version of gcc . gcc的Homebrew版本创建一个别名。 You can do this by adding a line similar to 您可以通过添加与

     alias hgcc='gcc-5' 

    to your .bashrc or .bash_profile . .bashrc.bash_profile What is even better is to add it to a file called .bash_aliases and then include it in your .bashrc or .bash_profile with 更好的是将其添加到名为.bash_aliases的文件中,然后将其包含在.bashrc.bash_profile

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

    We would then execute it via hgcc as in 然后,我们将通过hgcc执行它,如下所示

     $ hgcc main.c -fopenmp 

Aside: Installing gcc with OpenMP support on OS X 另外:在OS X上安装具有OpenMP支持的gcc

To install gcc with OpenMP support the easiest route to take is via Homebrew . 要安装带有OpenMP支持的gcc ,最简单的方法是通过Homebrew To do this you need to use the following command as per one of my previous answers 为此,您需要按照我之前的回答之一使用以下命令

brew install gcc --without-multilib

or if you have already installed gcc via Homebrew use 或者如果您已经通过Homebrew使用安装了gcc

brew reinstall gcc --without-multilib

This installs gcc as gcc-4.9 or gcc-5 (for both GCC 5.1 and GCC 5.2) depending on the version you have installed. 这将gcc安装为gcc-4.9gcc-5 (适用于GCC 5.1和GCC 5.2),具体取决于您安装的版本。 It does not create a symlink for gcc in /usr/local/bin and so when you execute gcc from the command line you will be calling Apple's clang version. 不会创建符号链接gcc/usr/local/bin ,当你执行等gcc从您将调用苹果铛版本的命令行。 You can verify this by running gcc -v which should produce a similar output to the below 您可以通过运行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

Checking Path is Set Correctly 检查路径设置正确

On (my Mac system at least) the default $PATH includes /usr/local/bin before /usr/bin as in 在(至少在我的Mac系统上)默认的$PATH/usr/bin之前包含/usr/local/bin

$ echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin

If this is not the case for you you will need to edit your .bashrc or .bash_profile and add 如果不是这种情况,则需要编辑.bashrc.bash_profile并添加

export PATH=/usr/local/bin:$PATH

This ensures that the Homebrew version of gcc will be found before any of the Apple versions, when we correct for Homebrew installing it as gcc-4.9 or gcc-5 . 这样可以确保在我们更正Homebrew将其安装为gcc-4.9gcc-5时,可以在所有Apple版本之前找到gcc的Homebrew版本。

What about setting OMP_NUM_THREADS environment variable? 如何设置OMP_NUM_THREADS环境变量? What would give you something like this? 什么会给你这样的东西?

 > OMP_NUM_THREADS=8 ./openMPExample.o

(BTW, having a binary which name ends with '.o' might not be such a good idea) (顺便说一句,使用以“ .o”结尾的二进制文件可能不是一个好主意)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM