OpenMP并行编程
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1. OpenMP 简介
1. OpenMP 简介
OpenMP并行编程模式
OpenMP是基于线程的并行编程模型。 OpenMP采用Fork-Join并行执行方式:
Master thread
F O R K
J I O N
F O R K
J I O N
串行部分
09:48
并行域
串行部分
并行域
串行部分
09:48
7
OpenMP并行编程
OpenMP简介
OpenMP编程制导
OpenMP库函数
OpenMP环境变量
2. OpenMP 编程制导
并行编译制导命令用来建立一组并行执行的线程, 这些线程执行给定的代码段。
格式:制导标识符 制导名称 [子句,]
( #pragma omp ) (parallel,for,section ,· ) · ·
库例程omp_get_num_threads()返回被使用的线程个数; 库例程 omp_get_thread_num()返回线程编号(0.. omp_get_num_threads()-1的一个整数),其中0号线程 表示主线程。
09:48 11
Hello world!, ThreadId=2 Hello world!, ThreadId=6 Hello world!, ThreadId=4 Hello world!, ThreadId=0 Hello world!, ThreadId=5 Hello world!, ThreadId=7 Hello world!, ThreadId=1 Hello world!, ThreadId=3
(privated, shared, reduction, copyin , · ) · ·
09:48 9
2. OpenMP 编程制导
2.1 OpenMP并行域制导
并行域就是一个能被多个线程并行执行的程序段 #pragma omp parallel [clauses]
{
structured_block }
#include “stdafx.h” #include “omp.h” void main(int argc, char* argv[]) { printf(“Hello from serial.\n”); printf(“Thread number = %d\n”,omp_get_thread_num()); #pragma omp parallel //开始并行执行 { printf (“Hello from parallel. Thread number=%d\n”,omp_get_thread_num()); } printf(“Hello from serial again.\n”);}
09:48 19
schedule (DYNAMIC [, chunksize]) :
划分迭代空间为chunksize大小的区间,然后基于先来先服务方式分配 给各线程; 当省略chunksize时,其默认值为1。
schedule (GUIDED [, chunksize])
类似于DYNAMIC调度,但区间开始大,然后迭代区间越来越少,循 环区间的划分是基于类似下列公式完成的(不同的编译系统可能不 同):
在sections语句结束处有一个隐含的路障,使用了nowait子句除外
09:48 13
void main(int argc, char* argv[]) section1 ThreadId=0 { section2 ThreadId=2 #pragma omp parallel sections section4 ThreadId=3 { section3 ThreadId=1 #pragma omp parallel section printf(“section1 ThreadId=%d\n”,omp_get_thread_num()); #pragma omp parallel section printf(“section2 ThreadId=%d\n”,omp_get_thread_num()); #pragma omp parallel section printf(“section3 ThreadId=%d\n”,omp_get_thread_num()); #pragma omp parallel section printf(“section4 ThreadId=%d\n”,omp_get_thread_num()); }}
建立多个线程,每个线程执行structured_block代码段。
09:48 10
2.1 OpenMP并行域制导
void main(int argc, char* argv[]) { #pragma omp parallel num_threads(8) { printf(“Hello world!, ThreadId=%d\n”,omp_get_thread_num()); } }
09:48 15
2.2.2并行for循环制导
并行for循环制导用来将循环划分成多个块,分配给各线程并行执行。 每个线程执行相同的 for 循环。 #pragma omp for [clauses] for 循环
注意: 循环变量是私有的。 可以将并行域和for制导结合成单一的简单形式 #pragma omp parallel for [clauses] { 循环体 }
09:48
16
int j=0; #pragma omp parallel j=1, ThreadId=1 { j=3, ThreadId=3 #pragma omp for j=2, ThreadId=2 for(j=0; j<4; j++) j=0, ThreadId=0 { printf(“j=%d,ThreadId =%d\n, j, omp_get_thread_num()); } } j=0, ThreadId=0 int j=0; j=1, ThreadId=0 #pragma omp for j=2, ThreadId=0 for(j=0; j<4; j++) j=3, ThreadId=0 { printf(“j=%d,ThreadId =%d\n, j, omp_get_thread_num()); }
09:48
14
void main(int argc, char* argv[]) { #pragma omp parallel sections { #pragma omp parallel section printf(“section1 ThreadId=%d\n”,omp_get_thread_num()); #pragma omp parallel section printf(“section2 ThreadId=%d\n”,omp_get_thread_num()); } section1 ThreadId=0 #pragma omp parallel sections section2 ThreadId=3 { section3 ThreadId=3 #pragma omp parallel section section4 ThreadId=1 printf(“section3 ThreadId=%d\n”,omp_get_thread_num()); #pragma omp parallel section printf(“section4 ThreadId=%d\n”,omp_get_thread_num()); } }
09:48 17
for循环调度字句
若线程个数与循环次数不相同,则for循环被分为若干部分,
使线程组中各线程负责其中的一部分;
也可以通过“schedule” 子句来分配for循环任务; 还可以以轮转的方式分配for循环任务。
调度子句SCHEDULE
迭代循环划分后的块大小和线程执行的块范围
schedule (kind[, chunksize])
R Sk k 2N
其中N是线程个数,Sk表示第k块的大小,Rk是剩余下未被调度的循环 迭代次数。 chunksize说明最小的区间大小。当省略chunksize时,其默认值为1。
schedule (RUNTIME)
调度选择延迟到运行时,调度方式取决于环境变量OMP_SCHEDULE 的值,例如: export OMP_SCHEDULE=DYNAMIC, 4; 使用 RUNTIME时,指明chunksize是非法的;
4
1. OpenMP 简介
使用Visual Studio 编写OpenMwk.baidu.com程序的必要步骤:
生成项目;
配置项目属性,支持OpenMP程序的编译和链接; 编写代码,加速#include
“omp.h”;
编写源程序;
配置环境变量,确定线程的数目; 执行程序。
【例1】并行hello
一种编译指导语句,能够显式指导多线程、共享内存 并行的应用程序编程接口(API) 由一组编译制导、运行时库函数和环境变量组成。 支持Fortran、C、C++ OpenMP能够支持多种平台,包括大多数的类UNIX 系统以及Windows NT系统,具有良好的可移植性 www.openmp.org
6
基于c/c++语言的OpenMP程序的结构
#include <omp.h> main (){ int var1, var2, var3; /*Serial code*/ … /*Beginning of parallel section. Fork a team ofthreads*/ /*Specify variable scoping */ #pragma omp parallel private(var1, var2) shared(var3) { /*Parallel section executed by all threads*/ … /*All threads join master thread and disband*/ } /*Resume serial code */ … }
2.2 OpenMP任务划分制导
任务划分并行制导可以出现在并行域内部,表明任务如 何在多个线程间分配,制导命令包括:
sections for single master
注意:这些结构不启动一组新线程,线程的启动在引入 parallel结构时就完成了。
09:48
12
2.2.1 SECTIONS制导:任务分配区
schedule (STATIC [, chunksize]) 每个线程的迭代是size次连续的迭
代计算
int i, S[1024]; S[0]=0; #pragma omp parallel for for(i=1; i<sizeof(S)/sizeof(int); i++) { S[i]=S[i-1]+i; S[k]=S[k-1]+k= S[k-2]+k-1+k=S[k-2]+2*k-1 } int i, S[1024]; S[0]=0; S[1]=1; #pragma omp parallel for schedule(static, 1) num_threads(2) for(i=2; i<sizeof(S)/sizeof(int); i++) { S[i]=S[i-2]+2*i-1; }
OpenMP并行编程
OpenMP简介 OPenMP编程制导 OpenMP库函数 OpenMP环境变量
1. OpenMP 简介
OpenMP---- 1997年, DEC, IBM, Intel, SGI, 和 Kuch & Associates 等公司的代表们制定的一种适用 于多种硬件平台的共享存储体系结构上编程的工业 应用标准
该结构表示由#pragma omp section引出的每个 structured_block可分配到并行区域的一组线程上并行执行。 #pragma sections[clauses] { [# pragma section] structured_block [# pragma section structured_block ] ………………….. }