基于openMP的并行计算实验.docx
- 文档编号:29559536
- 上传时间:2023-07-24
- 格式:DOCX
- 页数:14
- 大小:18.91KB
基于openMP的并行计算实验.docx
《基于openMP的并行计算实验.docx》由会员分享,可在线阅读,更多相关《基于openMP的并行计算实验.docx(14页珍藏版)》请在冰豆网上搜索。
基于openMP的并行计算实验
并行计算实验报告
课程:
并行计算
姓名:
郑波
学号:
44
班级:
计算机科学与技术13-2班
日期:
2015年12月7日
实验一:
OpenMP基本使用
一、实验目的
1、熟悉OpenMP编程。
2、比较串行算法与并行算法在执行时间上的差别;
3、考察线程数目使用不同对并行算法执行时间的影响;
4、考察运算规模N对串、并行算法执行时间上的影响。
二、实验内容
1、使用OpenMP进行两个矩阵A和B的加法,并分析串行、并行时间的差别以及问题规模对程序运行时间的影响
三、实验步骤
1、整个程序的设计流程
①全局变量设置三个宏定义过的size×size的二维数组啊a,b,c。
②初始化a数组为全1,b数组为全2
③通过omp_set_num_threads()库函数设置线程数
④调用openMP库函数omp_get_wtime()获取当前时间start
#pragmaompparallelfor开始做并行区部分
…
结束后再次调用omp_get_wtime()获取时间end,end-start即为并行消耗时间
⑤再次调用时间函数更新strat
串行做一边矩阵相加
更新end,end-start即为串行耗时
代码如下:
#include
#include<>
#definesize10000
usingnamespacestd;
inta[size][size],
b[size][size],
c[size][size];
intmain()
{
for(inti=0;i!
=size;++i)//initialthematrix
for(intj=0;j!
=size;++j){
a[i][j]=1;
b[i][j]=2;
}
doublestart=omp_get_wtime();
omp_set_num_threads(4);
#pragmaompparallelfor
for(inti=0;i for(intj=0;j c[i][j]=a[i][j]+b[i][j]; doubleend=omp_get_wtime(); cout<<"并行运行时间: "< start=omp_get_wtime(); for(inti=0;i for(intj=0;j c[i][j]=a[i][j]+b[i][j]; end=omp_get_wtime(); cout<<"串行运行时间: "< system("pause"); } 2、问题规模对串、并行程序时间的影响(A、B矩阵的大小为N*M) (1)通过不断增加问题规模,观察串行和并行程序的执行时间,得到如下表格的时间消耗数据: 100*100 1000*1000 10000*10000 串行消耗(ms) 并行消耗(ms) (2)可以发现,当矩阵规模较小时,串行算法仍然要比并行算法运行的快,当规模到达一定程度的时候,并行运行的速度较串行有了提升。 并行算法对各个CPU的调度也占用一定的时间,当问题规模很小的时候,这个调度时间占了很大的比重,而在规模较大的时候,这个调度时间就显得微乎其微了 3、线程数目对并行程序的影响(这里假设问题规模为: N*M=10000*10000) (1)在使用OpenMP进行并行执行矩阵加法时,我们可以自由设置进行并行计算的并行线程数目。 (2)在并行区域中,通过函数intomp_set_num_threads(int)设置并行区域中要创建的线程数,分别设置为2、4、8、16,得到如下表格的时间消耗 2 4 8 16 并行消耗(ms) (3)观察发现,在问题规模不变的前提下,随着线程数目的增加,问题解决的时间也在相应的减少。 但是,问题消耗的时间并不会随着线程数目的增加而不断的减少,原因可能是因为,随着线程数目的增减,线程的额外准备时间开销也将扩大。 四、心得体会 通过本次实验,了解了openMP库函数,掌握了openMP最基本的多线程程序编写。 通过分析比较串并行运行时间,体会了不同规模下串并行的使用效果。 实验二: 使用OpenMP实现圆周率计算的并行算法 一、实验目的 1、考察问题规模N对圆周率计算精确度的影响; 2、考察线程数目对圆周率计算执行时间的影响; 3、比较串、并行算法在执行时间上的差别。 二、实验内容 1、使用OpenMP和近似计算公式计算圆周率π的大小,并分析串行、并行时间的差别以及问题规模对程序运行时间的影响 三、实验步骤 1、整个程序的设计流程 ①全局变量设置宏size,用来描述计算范围 ②利用如下公式准备计算圆周率π的近似值 ③通过omp_set_num_threads()库函数设置线程数 ④调用openMP库函数omp_get_wtime()获取当前时间start #pragma? omp? parallel? for? reduction(+: sum) 开始做并行区部分 注意: 其中sum是共享的,因为是个连续和的问题,采用reduction之后,每个线程根据reduction(+: sum)的声明算出自己的sum,然后再将每个线程的sum加起来。 避免各个线程共享sum资源时出现问题 … 结束后再次调用omp_get_wtime()获取时间end,end-start即为并行消耗时间 ⑤再次调用时间函数更新strat 串行做一边矩阵相加 更新end,end-start即为串行耗时 代码如下: #include #include<> #define? size? using? namespace? std; int? main() { double? sum=0,start,end; omp_set_num_threads(4); start=omp_get_wtime(); #pragma? omp? parallel? for? reduction(+: sum) for(int? i=0;i sum+=4/(1+(+i)/size)*(+i)/size))*1/size; } end=omp_get_wtime(); cout<<"并行时间: "< sum=0; start=omp_get_wtime(); for(int? i=0;i sum+=4/(1+(+i)/size)*(+i)/size))*1/size; } end=omp_get_wtime(); cout<<"串行时间: "< (20); cout<<"π: "< system("pause"); } 2、问题规模对串、并行程序时间的影响(N的大小影响时间) (1)通过不断增加问题规模,观察串行和并行程序的执行时间,得到如下表格的时间消耗数据: 1000 100000 串行消耗(ms) 并行消耗(ms) (2)可以发现,当规模较小时,串行算法仍然要比并行算法运行的快,当规模到达一定程度的时候,并行运行的速度较串行有了提升。 并行算法对各个CPU的调度也占用一定的时间,当问题规模很小的时候,这个调度时间占了很大的比重,而在规模较大的时候,这个调度时间就显得微乎其微了 3、线程数目对并行程序的影响(这里假设问题规模为: N=100000) (1)在使用OpenMP进行并行执行运算时,我们可以自由设置进行并行计算的并行线程数目。 (2)在并行区域中,通过函数intomp_set_num_threads(int)设置并行区域中要创建的线程数,分别设置为2、4、8、16,得到如下表格的时间消耗 2 4 8 16 并行消耗(ms) (3)观察发现,在问题规模不变的前提下,随着线程数目的增加,问题解决的时间也在相应的减少。 但是,问题消耗的时间并不会随着线程数目的增加而不断的减少,原因可能是因为,随着线程数目的增减,线程的额外准备时间开销也将扩大。 四、心得体会 通过本次实验,进一步深入了openMP的编程,对openMP各线程共享资源、各自拥有自己的资源有了初步认识。 再一次体会到了并行计算给大规模计算带来的便利性。 实验三: 使用OpenMP求最大值 一、实验目的 1、掌握求最大值的并行算法 2、比较串行算法与并行算法在执行时间上的差别; 3、考察线程数目使用不同对并行算法执行时间的影响; 二、实验内容 1、使用OpenMP求一个乱序数列的最大值,并分析串行、并行时间的差别以及问题规模对程序运行时间的影响 三、实验步骤 1、整个程序的设计流程 本程序实现了平衡树算法,但由于处理器数目有限,并行结果反而不如串行,不过当处理器足够多时(理想情况为数组长度的一半)时,并行会有大的提升。 这里只讲一下平衡树算法思路。 1全局变量设置num×size的二维数组,最后一维用来保存数列 其中: num=log(size-1)/log (2)+1;表示平衡树的高度 ②初始化最后一维数组 ③通过omp_set_num_threads()库函数设置线程数 ④调用openMP库函数omp_get_wtime()获取当前时间start #pragmaompparallelfor开始做并行区部分 … 结束后再次调用omp_get_wtime()获取时间end,end-start即为并行消耗时间 ⑤算法核心部分: 算法先处理最后一层平衡树(假设个数为n),两个数据一组比较,取大的,生成新的一层平衡树(个数为n/2或者(n+1)/2),放在二维数组的上一维。 迭代处理每一层,最后使得新的一层个数为1,这个值就是最大值,即a[1][1]; 并行处理每一层平衡树 代码如下: #include #include<> #include<> constintsize=10000; usingnamespacestd; inta[size+1][size+1]; intmain() { intnum=log(size-1)/log (2)+1; for(size_ti=1;i<=size;++i){//初始化 a[num][i]=i; } intm=0; doublestart=omp_get_wtime(); for(size_ti=1;i<=size;++i)//串行 if(a[num][i]>=m) m=a[num][i]; doubleend=omp_get_wtime(); cout<<"串行: "< intamax=size; omp_set_num_threads(4); start=omp_get_wtime(); for(intk=num-1;k>=0;k--){ #pragmaompparallelfor for(intj=1;j<=(amax-1)/2+1;j++){ if(2*j>amax) a[k][j]=a[k+1][amax]; else a[k][j]=a[k+1][2*j-1]>a[k+1][2*j]? a[k+1][2*j-1]: a[k+1][2*j]; } } end=omp_get_wtime(); cout<<"并行: "< system("pause"); } 2、问题规模对串、并行程序时间的影响(数列长度为N) (1)通过不断增加问题规模,观察串行和并行程序的执行时间,得到如下表格的时间消耗数据: N 100 1000 10000 串行消耗(ms) 并行消耗(ms) (2)可以发现,并行总是比串行慢。 主要原因是: 平衡树算法对处理器个数有很高的要求,在处理器个数达到问题规模的一半的时候才有最好的效果,本机只有4个线程,线程的调度反而使得整个时间消耗比串行多。 3、线程数目对并行程序的影响(这里假设问题规模为: N*M=10000*10000) (1)在使用OpenMP进行并行执行矩阵加法时,我们可以自由设置进行并行计算的并行线程数目。 (2)在并行区域中,通过函数intomp_set_num_threads(int)设置并行区域中要创建的线程数,分别设置为2、4、8、16,得到如下表格的时间消耗 2 4 8 16 并行消耗(ms) (3)观察发现,在问题规模不变的前提下,随着线程数目的增加,问题解决的时间也在相应的减少。 但是,问题消耗的时间并不会随着线程数目的增加而不断的减少,原因可能是因为,随着线程数目的增减,线程的额外准备时间开销也将扩大。 四、心得体会 通过本次实验,学会了平衡树的算法设计思想,见识到了高性能计算在庞大任务规模面前的解决问题的能力。 在实验的过程中使用平衡树没有得到理想的结果,也说明了高性能计算在处理器方面的限制。 实验四: 使用OpenMP计算矩阵相乘 一、实验目的 1、掌握矩阵的乘法的串、并行算法 2、比较串行算法与并行算法在执行时间上的差别; 3、考察线程数目使用不同对并行算法执行时间的影响; 二、实验内容 1、给定两个矩阵A[N,M1]和B[M1,M]的乘积,即求C[N,M]=A[N,M1]*B[M1,M]。 三、实验步骤 1、整个程序的设计流程 计算矩阵的乘法,简单的使用三重循环完成,并行对最外层循环并行计算 1全局变量设置3个数组: a[M+1][N+1],b[N+1][M+1],c[M+1][M+1] ②初始化三个数组 ③通过omp_set_num_threads()库函数设置线程数 ④调用openMP库函数omp_get_wtime()获取当前时间start #pragmaompparallelfor开始做并行区部分 … 结束后再次调用omp_get_wtime()获取时间end,end-start即为并行消耗时间 代码如下: #include #include<> #define? M? 500 #define? N? 500 using? namespace? std; int? a[M+1][N+1],b[N+1][M+1],c[M+1][M+1]; int? main() { //init? array for(int? i=1;i<=M;i++) for(int? j=1;j<=N;j++) a[i][j]=1; for(int? i=1;i<=N;i++) for(int? j=1;j<=M;j++) b[i][j]=2; //parallel? do omp_set_num_threads(4); double? start=omp_get_wtime(); #pragma? omp? parallel? for for(int? i=1;i<=M;i++) for(int? j=1;j<=M;j++) for(int? k=1;k<=N;k++) c[i][j]+=a[i][k]*b[k][j]; double? end=omp_get_wtime(); cout<<"并行: "< //serial? do start=omp_get_wtime(); for(int? i=1;i<=M;i++) for(int? j=1;j<=M;j++) for(int? k=1;k<=N;k++) c[i][j]+=a[i][k]*b[k][j]; end=omp_get_wtime(); cout<<"串行: "< system("pause"); } 2、问题规模对串、并行程序时间的影响(二维数组为N*N) (1)通过不断增加问题规模,观察串行和并行程序的执行时间,得到如下表格的时间消耗数据: N 100 300 10000 串行消耗(ms) 并行消耗(ms) (2)可以发现,当规模较小时,串行算法仍然要比并行算法运行的快,当规模到达一定程度的时候,并行运行的速度较串行有了提升。 并行算法对各个CPU的调度也占用一定的时间,当问题规模很小的时候,这个调度时间占了很大的比重,而在规模较大的时候,这个调度时间就显得微乎其微了 3、线程数目对并行程序的影响(这里假设问题规模为: N*M=500*500) (1)在使用OpenMP进行并行执行矩阵加法时,我们可以自由设置进行并行计算的并行线程数目。 (2)在并行区域中,通过函数intomp_set_num_threads(int)设置并行区域中要创建的线程数,分别设置为2、4、8、16,得到如下表格的时间消耗 2 4 8 16 并行消耗(ms) (3)观察发现,在问题规模不变的前提下,随着线程数目的增加,问题解决的时间也在相应的减少。 但是,问题消耗的时间并不会随着线程数目的增加而不断的减少,原因可能是因为,随着线程数目的增减,线程的额外准备时间开销也将扩大。 四、心得体会 挺水的一次实验,不是因为实验水,而是感觉跟第一次实验没什么区别,线程只是利用线程数去减少了时间开销,而不是降低了问题的复杂度。 主要是矩阵的乘法,自己没有用到好的算法。 不过目前计算矩阵的乘法还没有找到O(n^2)或者比O(n^2)时间复杂度更小的算法吧
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于 openMP 并行 计算 实验