矩阵乘法的OpenMP实现及性能分析

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 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;

.....此处代表实际的矩阵乘法代码

相关文档
最新文档