南开大学并行程序设计2019Word格式.doc

上传人:b****9 文档编号:13022004 上传时间:2022-10-02 格式:DOC 页数:10 大小:98KB
下载 相关 举报
南开大学并行程序设计2019Word格式.doc_第1页
第1页 / 共10页
南开大学并行程序设计2019Word格式.doc_第2页
第2页 / 共10页
南开大学并行程序设计2019Word格式.doc_第3页
第3页 / 共10页
南开大学并行程序设计2019Word格式.doc_第4页
第4页 / 共10页
南开大学并行程序设计2019Word格式.doc_第5页
第5页 / 共10页
点击查看更多>>
下载资源
资源描述

南开大学并行程序设计2019Word格式.doc

《南开大学并行程序设计2019Word格式.doc》由会员分享,可在线阅读,更多相关《南开大学并行程序设计2019Word格式.doc(10页珍藏版)》请在冰豆网上搜索。

南开大学并行程序设计2019Word格式.doc

1、论文应详细描述清楚所研究的问题,并行算法的设计。

2、鼓励大家选择课堂教学之外的问题,通过文献调研,研究其并行求解方法,甚至有自己提出新的方法。

3、最好能有求解一个问题的多种并行算法之间的对比分析。

1、应调研较新的工具,避免调研太“古老”的工具。

2、不能只是工具相关资料的调研和文字的汇总、整理,重点仍是并行编程——用调研的工具编程解决一个具体问题。

3、鼓励大家进行不同并行编程工具间的对比,例如调研的工具与课堂讲授的工具之间的对比。

三、论文写作格式要求:

论文题目要求为宋体三号字,加粗居中;

正文部分要求为宋体小四号字,标题加粗,行间距为1.5倍行距;

应符合科技论文写作规范,题目、摘要、关键字、章节、参考文献等等完整、正确。

这方面可参考附件范文。

四、论文提交注意事项:

1、论文一律以此文件为封面,写明学习中心、专业、姓名、学号等信息。

论文保存为word文件,以“课程名+学号+姓名”命名。

2、论文一律采用线上提交方式,在学院规定时间内上传到教学教务平台,逾期平台关闭,将不接受补交。

3、不接受纸质论文。

4、与论文一同打包提交源程序,注意,是提交.cpp、.h等源程序,不要将工程文件、编译后的目标文件等打包提交。

5、如有抄袭雷同现象,将按学院规定严肃处理。

矩阵相乘并行化处理

摘要:

矩阵相乘是一个比较复杂的计算。

本次实验分别使用串行算法、Cache优化算法、SSE编程和分片策略算法实现了矩阵乘法运算,实验采用同一个样本,即矩阵大小为512个元素,元素值为由时间生成的随机数,每个算法对此样本运行十次,并记录每次运行时间和十次运算的平均运行时间。

通过不同算法结果来讨论不同并行编程方法对性能的影响。

关键词:

矩阵相乘;

并行化;

SSE编程;

分片策略;

串行算法

一、引言

矩阵相乘最重要的方法是一般矩阵乘积。

它只有在第一个矩阵的列数(column)和第二个矩阵的行数(row)相同时才有意义。

一般单指矩阵乘积时,指的便是一般矩阵乘积。

一个m×

n的矩阵就是m×

n个数排成m行n列的一个数阵。

由于它把许多数据紧凑的集中到了一起,所以有时候可以简便地表示一些复杂的模型,如电力系统网络模型。

本文通过实验分别使用串行算法、Cache优化算法、SSE编程和分片策略算法实现了矩阵乘法运算,实验采用同一个样本,即矩阵大小为512个元素,元素值为由时间生成的随机数,每个算法对此样本运行十次,并记录每次运行时间和十次运算的平均运行时间。

二、试验环境

属性

操作系统

macOSHighSierra10.13.5

物理内核数

2个

编程语言

C/C++

内存大小

8GB

编译器

VSCODE

三、矩阵相乘并行化分析

1数据初始化

在矩阵样本设计方面,考虑大越大规模的数据越能体现不同算法在运行上的差距,因而将矩阵大小设置为512个元素,并且为了减少元素数据对实验的影响,采取了随机数赋值的方法。

代码如下:

srand((unsigned)time(NULL));

floata[maxN][maxN];

floatb[maxN][maxN];

for(inti=0;

i<

n;

i++)

{

for(intj=0;

j<

j++){

a[i][j]=rand();

b[i][j]=rand();

}

}

2串行算法

由于矩阵乘法规则为乘积AB的第i个分量等于矩阵A的第i个行向量与列向量B的对应分量乘积之和,因而对矩阵A的每一行的元素,矩阵B的每一列的元素都要与之相乘并相加,所以需要先遍历矩阵A一行中的元素的同时遍历矩阵B一列中的元素,再遍历矩阵B中的每一列,再遍历矩阵A中的每一行,三层遍历嵌套,时间复杂度O(n)=n^3,用clock_t记录时间。

具体代码如下:

doublemul(intn,floata[][maxN],floatb[][maxN],floatc[][maxN]){//串行算法O(n)=n^3

doubletime;

clock_tstart,end;

start=clock();

for(inti=0;

{

for(intj=0;

j++)

{

c[i][j]=0.0;

for(intk=0;

k<

k++){

c[i][j]+=a[i][k]*b[k][j];

}

}

}

end=clock();

time=(double)(end-start);

cout<

<

"

串行算法耗时:

"

(time/CLOCKS_PER_SEC)<

s"

endl;

returntime/CLOCKS_PER_SEC;

}

3Cache优化

由于寄存器从内存中取值时,需要从内存中寻址,上述串行算法b[k][j]需要先对矩阵B的行进行遍历,又因为在c++中,二维数组相邻的元素地址相近,因而先对行进行遍历造成了地址跳跃,需要更长的寻址时间。

将矩阵B转置,就能够实现对连续的地址进行读写操作,节省大量寻址时间。

算法时间复杂度O(n)=n^3。

doubletrans_mul(intn,floata[][maxN],floatb[][maxN],floatc[][maxN]){//Cache优化O(n)=n^3

for(inti=0;

++i)

for(intj=0;

i;

++j)

swap(b[i][j],b[j][i]);

++i){

++j){

c[i][j]=0.0;

for(intk=0;

++k){

c[i][j]+=a[i][k]*b[j][k];

}

}//transposition

Cache优化耗时:

4SSE并行化

基于SIMD编程,将多个元素同时进行寄存器加载和存储器存值等操作能够提高并行效率。

使用SSE指令能够实现该功能。

时间复杂度为O(n)=(n^3)/4,同样对矩阵B进行转置。

doublesse_mul(intn,floata[][maxN],floatb[][maxN],floatc[][maxN]){//SSE版本O(n)=(n^3)/4

__m128t1,t2,sum;

//__m128==float

++i){

++j){

sum=_mm_setzero_ps();

//Initialize

for(intk=n-4;

k>

=0;

k-=4){//sumevery4elements

t1=_mm_loadu_ps(a[i]+k);

t2=_mm_loadu_ps(b[j]+k);

t1=_mm_mul_ps(t1,t2);

sum=_mm_add_ps(sum,t1);

sum=_mm_hadd_ps(sum,sum);

_mm_store_ss(c[i]+j,sum);

for(intk=(n%4)-1;

--k){//handlethelastn%4elements

}

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 解决方案 > 商业计划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1