[多线程/并行编程]配置 openmp/libgomp 库

C/C++第三方开源库的介绍和相关讨论
回复
头像
523066680
Administrator
Administrator
帖子: 573
注册时间: 2016年07月19日 12:14
联系:

[多线程/并行编程]配置 openmp/libgomp 库

帖子 523066680 »

http://openmp.org的描述是:The OpenMP API specification for parallel programming

关于这个库的获取
  1. 安装TDM-GCC (4.x版本或以上)的时候,带有omp.h,但实际没有解压相关库文件,需要在安装时点开选项列表,选中openmp再安装
    图片
  2. tdm-gcc.tdragon.net/download Packages 下方的列表中下载 gcc-5.1.0-tdm64-1-openmp.zip
    或者从 Sourceforege - tdm-gcc 页面 中下载 gcc-5.1.0-tdm64-1-openmp.zip,里面已经包含32位和64位的静态库和动态库
源码在gcc源码包中(sourceforge):
TDM-GCC MinGW Compiler Sources / Vanilla Sources / gcc-5.1.0.tar.bz2
MinGW MinGW / Base / gcc / Version5 / gcc-5.3.0-2 / gcc-5.3.0-2-mingw32-src.tar.xz

示例代码
https://github.com/OpenMP/Examples

编译器支持
主流C/C++编译器,如gcc与visual C++,都内在支持OpenMP。一般都必须在程序中#include <omp.h>

Visual C++需要在IDE的编译选项->语言->支持OpenMP。这实际上使用了编译选项/openmp
优点和缺点

优点
可移植的多线程代码(在C/C++和其他语言中,人们通常为了获得多线程而调用特定于平台的原语)
简单,没必要向MPI中那样处理消息传递
增量并行,一次可以只在代码的一部分执行,对代码不需要显著的改变
统一的顺序执行和并行执行的代码,在顺序执行编译器上,OpenMP的执行按照注释进行对待;

缺点
存在引入难以调试的同步错误和竞争条件的风险
目前,只能在共享内存的多处理器平台高效运行
需要一个支持OpenMP的编译器
可扩展性是受到内存架构的限制
不支持比较和交换
在GPU上不能使用
多线程的可执行文件的启动需要更多的时间,可能比单线程的运行的慢,因此,使用多线程一定要有其他有优势的地方
很多情况下使用多线程不仅没有好处,还会带来一些额外消耗
gcc-5.1.0-tdm64-1-openmp.zip
(313.17 KiB) 已下载 88 次
omp.h
(4.25 KiB) 已下载 70 次
分割线
头像
523066680
Administrator
Administrator
帖子: 573
注册时间: 2016年07月19日 12:14
联系:

编译示例代码

帖子 523066680 »

示例代码:
#include <stdio.h>

int main(int argc, char *argv[] )
{
#pragma omp parallel
{
printf("TEST\n");
}
return 0;
}
编译

使用 Nuwen.net 提供的离线MinGW环境
  • 这个程序直接 gcc example.c 就可以通过,运行输出一行 TEST,原因就是没有开启openmp开关。
    > gcc example.c -fopenmp gcc: error: libgomp.spec: No such file or directory
    将 gcc-5.1.0-tdm64-1-openmp.zip 中的 libgomp.a, libgomp.spec 放在当前目录
    > gcc example.c -fopenmp c:/mingw/bin/../lib/gcc/x86_64-w64-mingw32/6.1.0/../../../../x86_64-w64-mingw32/ bin/ld.exe: cannot find -lgomp c:/mingw/bin/../lib/gcc/x86_64-w64-mingw32/6.1.0/../../../../x86_64-w64-mingw32/ bin/ld.exe: cannot find -lpthread
    添加编译参数 -L.
    但是 libpthread.a 就只有在tdm-gcc-64 中能找到,也复制到当前目录
    > gcc example.c -fopenmp -L. > a TEST TEST TEST TEST TEST TEST TEST TEST
    直接 gcc example.c -L. -I. -lgomp 虽然编译通过,但也是达不到多线程的效果的,必须开启 -fopenmp
使用tdm-gcc-64 or tdm-gcc-32
  • PATH=D:\tdm-gcc-32\bin

    静态链接
    将 libgomp.a 放在当前目录下(注意辨别64位/32位)
    > gcc example.c -fopenmp -L.
    编译后即可运行

    动态链接
    > gcc example.c -fopenmp
    将 libgomp_64-1.dll 或者 libgomp-1.dll 放在运行环境中方可运行。
头像
523066680
Administrator
Administrator
帖子: 573
注册时间: 2016年07月19日 12:14
联系:

Re: [多线程/并行编程]配置 openmp/libgomp 库

帖子 523066680 »

第二个示例(当用到omp相关的函数时,就需要 #include <omp.h> 了 )
#include <stdio.h>
#include <omp.h>

int main(int argc, char *argv[] )
{
#pragma omp parallel num_threads(6)
{
printf("Thread %d\n", omp_get_thread_num() );
}
return 0;
}
openmp>set path=D:\TDM-GCC-32\BIN openmp>gcc get_thread_num.c -o get_thread_num -fopenmp -L. openmp>get_thread_num Thread 2 Thread 4 Thread 1 Thread 0 Thread 3 Thread 5
相关教程和文章,暂时贴这里了
[ibm.com]通过 GCC 学习 OpenMP 框架

wikipedia

GCC在线手册 - libgomp
头像
523066680
Administrator
Administrator
帖子: 573
注册时间: 2016年07月19日 12:14
联系:

Re: [多线程/并行编程]配置 openmp/libgomp 库

帖子 523066680 »

omp_get_max_threads() 获取最大线程数

一般默认是和CPU核数相同,比如8核,那么调用这个函数返回8。4核返回4
但是这个限制也可以自己手动修改,比如
omp_set_num_threads( 16 );
但是我想,如果是大量运算的话,把线程改的特别多也没有意义,因为硬件限制在那里。


为 for 提供多线程处理

假设有一个函数,里面的操作相对耗时(比如和网络有关),需要2秒( 暂时用 usleep 表示 )
就可以用openmp 实现并行,但是执行顺序不是线性的
#include <stdio.h>
#include <omp.h>
#include <unistd.h>

void func(long i)
{
usleep(999999);
usleep(999999);
printf("%d ", i);
}

int main(int argc, char *argv[] )
{
long i;
long N = 32;

omp_set_num_threads( 8 ); //设置线程数
#pragma omp parallel for
for (i=0; i<N; ++i)
{
func(i);
}
return 0;
}
输出结果
4 12 16 8 24 0 20 28 13 29 5 21 1 9 25 17 2 10 14 30 18 6 26 22 3 11 19 27 15 31
7 23
回复

在线用户

正浏览此版面之用户: 没有注册用户 和 0 访客