矩阵乘法的OpenMP实现及性能分析
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一. 实验目的
1) 用OpenMP 实现最基本的数值算法“矩阵乘法” 2) 掌握for 编译制导语句 3) 对并行程序进行简单的性能
二. 实验环境
1) 硬件环境:32核CPU 、32G 内存计算机;
2) 软件环境:Linux 、Win2003、GCC 、MPICH 、VS2008;
4) Windows 登录方式:通过远程桌面连接,用户名和初始密码都是自己的学号。
三. 实验内容
1. 用OpenMP 编写两个n 阶的方阵a 和b 的相乘程序,结果存放在方阵c 中,其中乘法用for 编译制导语句实现并行化操作,并调节for 编译制导中schedule 的参数,使得执行时间最短,写出代码。 方阵a 和b 的初始值如下:
⎥⎥⎥⎥⎥⎥⎥⎥⎦
⎤⎢⎢⎢⎢⎢⎢⎢⎢⎣⎡-++++=12,...,2,1,..2,...,5,4,31,...,4,3,2,...,3,2,1n n n n n n n a ⎥⎥⎥⎥⎥⎥⎥⎥⎦
⎤⎢⎢⎢⎢⎢⎢⎢⎢⎣⎡=
1,...,1,1,1..1,...,1,1,11,...,1,1,11,...,
1,1,1b 输入:
方阵的阶n 、并行域的线程数 输出:
c 中所有元素之和、程序的执行时间 提示:
a,b,c 的元素定义为int 型,c 中所有元素之各定义为long long 型。 Windows 计时:
用<>中的clock_t clock( void )函数得到当前程序执行的时间 Linux 计时:
#include
timeval start,end;
gettimeofday(&start,NULL);
gettimeofday(&end,NULL);
cout<<"execution time:"<< 1000000<<"seconds" < 答: 在windows下使用Microsofe Visual Studio编程,源代码如下: #include<> #include<> #include<> #define NN 2000 int a[NN][NN], b[NN][NN]; long long c[NN][NN]; void solve(int n, int num_thread) { int i, j, t, k, time; clock_t startTime, endTime; long long sum; omp_set_num_threads(num_thread); for(i=0;i 验结果。 答:串行执行时程序的执行时间为:T = 加速比=顺序执行时间/并行执行时间 效率=加速比/节点数 表1 不同节点数下程序的执行时间(秒) 节点数 实验结果 12481632 第1次 第2次 第3次 第4次 第5次 平均值 图1 不同节点数下程序的执行时间 图2 不同节点数下程序的加速比 图3 不同节点数下程序的效率 执行时间的分析: 随着节点数的增加,程序的执行时间减少,大概可以从结果中得出,随着节点书的增加一倍,执行时间减少一半 加速比的分析: 随着节点数的增加,程序的加速比增加,大概可以从结果中得出,随着节点书的增加一倍,加速相应的增加接近一倍 效率的分析: 随着节点数的增加,程序的效率逐渐减少 3.分析矩阵相乘程序的问题规模与效率的关系:固定节点数为4,让方阵阶从200到1600之间变化,每隔100取一个值。(为了减少时间,每项实验可只执行1次) 答: 表2 相同节点数下不同问题规模程序的执行时间与效率 方阵阶数 并行执 行时间串行执 行时间 效率 200 300 400 500 600 700 800 900 1000 1100 1200 1300 1400 1500 1600 图不同问题规模下程序的效率 问题规模与效率的关系分析: 随着问题规模的增加,程序的效率趋于稳定,但是略微有点下降。 嵌套循环中,如果外层循环迭代次数较少时,如果将来CPU核数增加到一定程度时,创建 的线程数将可能小于CPU核数。另外如果内层循环存在负载平衡的情况下,很难调度外层循环使之达到负载平衡。 下面以矩阵乘法作为例子来讲述如何将嵌套循环并行化,以满足上述扩展性和负载平衡需求。 一个串行的矩阵乘法的函数代码如下: /**矩阵串行乘法函数 @param int*a -指向要相乘的第个矩阵的指针 @param int row_a -矩阵a的行数 @param int col_a -矩阵a的列数 @param int *b –指向要想成的第个矩阵的指针 @param int row_b -矩阵b的行数 @param int col_b -矩阵b的列数 @param int *c -计算结果的矩阵的指针 @param int c_size -矩阵c的空间大小(总元素个数) @return void –无 */ void Martrix_Multiply(int *a, int row_a,int col_a, int*b,int row_b,int col_b, int*c,int c_size) { If(col_a!=row_b||c_size { return; } int i,j,k; .....此处代表实际的矩阵乘法代码