C OpenMP parallel for loop is not 运行 on multiple thread
C OpenMP parallel for loop is not running on more than one thread
我正在尝试一个简单的 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.
设置OMP_NUM_THREADS
环境变量怎么样?
什么会给你这样的东西?
> OMP_NUM_THREADS=8 ./openMPExample.o
(顺便说一句,拥有一个名称以“.o”结尾的二进制文件可能不是一个好主意)
您正在使用不支持 OpenMP 的 Apple clang 版本 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
。如果不是这种情况,最后有一节介绍如何通过支持 OpenMP 的 Homebrew 安装 gcc
。
Homebrew 将 gcc
安装为 gcc-4.9
或 gcc-5
(对于 GCC 5.1 和GCC 5.2) 取决于您安装的版本。它 而不是 在 /usr/local/bin
中为 gcc
创建符号链接,因此当您从命令行执行 gcc
时,您将调用 Apple 的 clang 版本。这是我们必须纠正的,我们可以通过多种方式使用 Homebrew 版本的 gcc
而不是 Apple 的 clang 版本
通过
显式执行gcc
$ gcc-5 main.c -fopenmp
使用以下命令在 /usr/local/bin
中为 gcc
创建符号链接
$ cd /usr/local/bin
$ ln -s gcc-5 gcc
现在,当您执行 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)
为 gcc
的 Homebrew 版本创建一个别名。您可以通过添加类似于
的行来执行此操作
alias hgcc='gcc-5'
到您的 .bashrc
或 .bash_profile
。更好的方法是将它添加到一个名为 .bash_aliases
的文件中,然后将其包含在您的 .bashrc
或 .bash_profile
和
中
[[ -f ~/.bash_aliases ]] && . ~/.bash_aliases
然后我们将通过 hgcc
执行它,如
$ hgcc main.c -fopenmp
旁白:在 OS X
上安装支持 OpenMP 的 gcc
要安装支持 OpenMP 的 gcc
,最简单的途径是通过 Homebrew。为此,您需要根据
使用以下命令
brew install gcc --without-multilib
或者如果您已经通过 Homebrew 安装 gcc
使用
brew reinstall gcc --without-multilib
这会将 gcc
安装为 gcc-4.9
或 gcc-5
(对于 GCC 5.1 和GCC 5.2) 取决于您安装的版本。它 而不是 在 /usr/local/bin
中为 gcc
创建符号链接,因此当您从命令行执行 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
检查路径设置是否正确
开启(至少我的 Mac 系统)默认 $PATH
在 /usr/bin
之前包括 /usr/local/bin
,如
$ echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
如果您不是这种情况,您需要编辑 .bashrc
或 .bash_profile
并添加
export PATH=/usr/local/bin:$PATH
当我们将 Homebrew 安装为 gcc-4.9
或 gcc-5
.[=68 时,这可确保在任何 Apple 版本之前找到 gcc
的 Homebrew 版本=]
我正在尝试一个简单的 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.
设置OMP_NUM_THREADS
环境变量怎么样?
什么会给你这样的东西?
> OMP_NUM_THREADS=8 ./openMPExample.o
(顺便说一句,拥有一个名称以“.o”结尾的二进制文件可能不是一个好主意)
您正在使用不支持 OpenMP 的 Apple clang 版本 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
。如果不是这种情况,最后有一节介绍如何通过支持 OpenMP 的 Homebrew 安装 gcc
。
Homebrew 将 gcc
安装为 gcc-4.9
或 gcc-5
(对于 GCC 5.1 和GCC 5.2) 取决于您安装的版本。它 而不是 在 /usr/local/bin
中为 gcc
创建符号链接,因此当您从命令行执行 gcc
时,您将调用 Apple 的 clang 版本。这是我们必须纠正的,我们可以通过多种方式使用 Homebrew 版本的 gcc
而不是 Apple 的 clang 版本
通过
显式执行gcc
$ gcc-5 main.c -fopenmp
使用以下命令在
/usr/local/bin
中为gcc
创建符号链接$ cd /usr/local/bin $ ln -s gcc-5 gcc
现在,当您执行
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)
为
的行来执行此操作gcc
的 Homebrew 版本创建一个别名。您可以通过添加类似于alias hgcc='gcc-5'
到您的
中.bashrc
或.bash_profile
。更好的方法是将它添加到一个名为.bash_aliases
的文件中,然后将其包含在您的.bashrc
或.bash_profile
和[[ -f ~/.bash_aliases ]] && . ~/.bash_aliases
然后我们将通过
hgcc
执行它,如$ hgcc main.c -fopenmp
旁白:在 OS X
上安装支持 OpenMP 的gcc
要安装支持 OpenMP 的 gcc
,最简单的途径是通过 Homebrew。为此,您需要根据
brew install gcc --without-multilib
或者如果您已经通过 Homebrew 安装 gcc
使用
brew reinstall gcc --without-multilib
这会将 gcc
安装为 gcc-4.9
或 gcc-5
(对于 GCC 5.1 和GCC 5.2) 取决于您安装的版本。它 而不是 在 /usr/local/bin
中为 gcc
创建符号链接,因此当您从命令行执行 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
检查路径设置是否正确
开启(至少我的 Mac 系统)默认 $PATH
在 /usr/bin
之前包括 /usr/local/bin
,如
$ echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
如果您不是这种情况,您需要编辑 .bashrc
或 .bash_profile
并添加
export PATH=/usr/local/bin:$PATH
当我们将 Homebrew 安装为 gcc-4.9
或 gcc-5
.[=68 时,这可确保在任何 Apple 版本之前找到 gcc
的 Homebrew 版本=]