矩阵相乘 并行算法
- 格式:doc
- 大小:545.50 KB
- 文档页数:32
矩阵乘法运算规则
矩阵乘法是一种常见的数学运算,它可以用来计算两个矩阵的乘积。
矩阵乘法的规则是:
两个矩阵A和B的乘积C=A*B,其中A是m×n矩阵,B是n×p矩阵,则C是m×p矩阵。
矩阵乘法的计算公式是:Cij=∑k=1nAikBkj,其中Cij是矩阵C的第i行第j列元素,Aik
是矩阵A的第i行第k列元素,Bkj是矩阵B的第k行第j列元素,n是矩阵A的列数,
也是矩阵B的行数。
矩阵乘法的运算规则是:矩阵A和B的乘积C=A*B,其中A是m×n矩阵,B是n×p矩阵,则C是m×p矩阵,其中Cij=∑k=1nAikBkj,其中Cij是矩阵C的第i行第j列元素,Aik
是矩阵A的第i行第k列元素,Bkj是矩阵B的第k行第j列元素,n是矩阵A的列数,
也是矩阵B的行数。
矩阵乘法的运算规则是非常重要的,它可以用来解决许多数学问题,例如线性方程组、矩阵的幂运算、矩阵的逆运算等。
此外,矩阵乘法还可以用来计算矩阵的行列式、特征值和特征向量等。
矩阵乘法的运算规则是非常重要的,它可以用来解决许多数学问题,并且在计算机科学中
也有着广泛的应用。
因此,学习矩阵乘法的运算规则是非常有必要的,可以帮助我们更好
地理解和应用矩阵乘法。
一、介绍Matlab是一种用于数学建模、仿真和数据分析的高级编程语言和交互式环境。
在矩阵乘法运算中,Matlab提供了许多优化和并行化的方法,以加快矩阵乘法的计算速度。
本文将详细介绍Matlab中矩阵乘法并行运算的相关知识和技巧。
二、矩阵乘法概述矩阵乘法是线性代数中常见的基本运算,它用于将两个矩阵相乘得到一个新的矩阵。
在Matlab中,矩阵乘法可以使用'*'操作符进行计算。
如果有两个矩阵A和B,它们的矩阵乘法可以表示为C=A*B,其中C 是结果矩阵。
通常情况下,矩阵乘法的计算过程是相当消耗计算资源的。
三、Matlab中的矩阵乘法优化在Matlab中,针对矩阵乘法的优化有许多方法,例如使用专门的矩阵乘法函数、改进矩阵存储方式和并行计算等。
其中,并行计算是加速矩阵乘法计算速度的重要方法之一。
1. Matlab矩阵乘法函数Matlab提供了一系列专门用于矩阵乘法计算的函数,如matmul、mmx等。
这些函数内部已经做了很多优化,能够充分利用计算资源,并且可以适应不同硬件的优化。
2. 改进矩阵存储方式在Matlab中,矩阵可以使用不同的存储方式,如稀疏矩阵、密集矩阵和块状矩阵等。
选择合适的矩阵存储方式可以减少内存占用,提高运算速度。
3. 并行计算Matlab中的并行计算工具箱提供了丰富的并行化函数和工具,可以通过多线程和分布式计算等方式加速矩阵乘法的计算速度。
通过并行计算,可以利用多核处理器和集群计算资源,实现矩阵乘法的并行计算。
四、Matlab中的矩阵乘法并行计算在Matlab中,矩阵乘法的并行计算可以通过多种方式实现。
以下将详细介绍几种常见的矩阵乘法并行计算方法:1. 使用matlabpool进行并行计算Matlab中的matlabpool函数可以方便地创建一个本地并行计算池,通过该计算池可以并行计算矩阵乘法。
通过设置并行计算池的大小和Worker节点的数量,可以充分利用多核处理器的计算资源。
大规模矩阵相乘的并行算法
作者:朱彦辑国佳佳
来源:《电脑知识与技术》2017年第18期
摘要:在大型的科学计算中,矩阵乘法运算是耗时较多的运算,也是工程数值计算中一种常见的运算方式。
串行计算程序由于计算时间和计算效率不尽人意,已经不能满足人们的需求,为了降低计算所消耗的时间,人们一直在研究合适的可用于并行的计算矩阵相乘的方法,和串行算法相比,矩阵相乘的并行算法要考虑更多方面的问题。
该文通过运用API,OpenMP 多核并行计算,将矩阵按一定规则分块传入每个进程,分别进行矩阵相乘运算,这样可以将计算时间缩短大半。
关键词:矩阵相乘;API多核并行;OpenMP并行
中图分类号:TP311 文献标识码:A 文章编号:1009-3044(2017)18-0059-03。
多核软件设计实验指导――OpenMP矩阵相乘开发者:开发时间:版本号:一. 问题描述矩阵相乘是线性代数中最常见的问题之一,它在数值计算中有广泛的应用,在计算机的世界里,矩阵相乘扮演着一个不可或缺的角色。
设A 和B 是2个 n n ⨯ 矩阵,,它们的乘积AB 同样是一个n n ⨯矩阵。
A 和B 乘积矩阵C 中元素C ]][[]][[1]][[j k B k i A nk j i ∑==二、串行算法描述若以上面的定义来计算A 和B 的乘积矩阵C ,则每计算C 的一个元素]][[j i C ,需要作n 次乘法运算和n -1次加法运算。
因此,算出矩阵C 的2n 个元素所需的计算时间为)(3n O 。
从程序运行的效率上来分析,如果n 比较大的时候,会耗费大量的空间和时间。
20世纪60年代末期,Strassen 采用了类似在大整数乘法中用过的分治技术,将计算2个n 阶矩阵乘积所需的计算时间改进到)()(81.27log n n O =O ,其基本思想还是使用分治法。
显然,这也没能够大幅度地提高运行速度和效率。
将矩阵a 与矩阵b 相乘得到矩阵c 的代码如下:for(i=0;i<dim;i++){ for(j=0;j<dim;j++){ c(i,j)=0;for(k=0;k<dim;k++){c(i ,j)+=a(i ,k)*b(k,j);}}}三、并行算法下面使用了OpenMP ,修改后的矩阵相乘程序使最外面的迭代在多个线程间静态分割,如图(a )所示:#pragma omp paralllel default(private) shared(a,b,c,dim) num_threads(2) #pragma omp for schedule(static)for(i=0;i<dim;i++){ for(j=0;j<dim;j++){ c(i,j)=0;for(k=0;k<dim;k++){c(i ,j)+=a(i ,k)*b(k,j);}}}Static调度类的一般形式为schedule(static[,chunk-size])。
超级计算技术中的并行算法与矩阵运算在现代科学和工程领域中,超级计算技术发挥着至关重要的作用。
为了解决复杂问题,超级计算机采用了并行算法和矩阵运算等技术,以实现高效的计算和分析。
本文将探讨超级计算技术中的并行算法和矩阵运算,并分析其应用与发展趋势。
首先,我们来了解一下超级计算技术中的并行算法。
并行算法是指将复杂的计算任务分解成多个子任务,然后并发地运行于多个计算单元上,以提高计算效率和性能。
并行算法的设计需要考虑任务分解、通信和同步等关键问题。
常用的并行算法包括分治法、并行排序和并行搜索等。
对于矩阵运算来说,超级计算技术也发挥着重要的作用。
矩阵运算是指对矩阵进行基本的数学运算,诸如加法、减法、乘法和求逆等。
这些矩阵运算在科学计算、图像处理和人工智能等领域中广泛应用。
超级计算技术能够利用并行算法加速矩阵运算的速度,提高计算效率。
在超级计算技术中,矩阵乘法是一种常见且重要的矩阵运算。
矩阵乘法的基本思想是将两个矩阵相乘,得到一个新的矩阵。
然而,传统的矩阵乘法算法在大规模矩阵计算时效率较低,因此需要并行算法的支持。
并行矩阵乘法算法采用了多种策略,如按块分配、循环分配和网络划分等,以充分利用计算资源。
除了矩阵乘法,超级计算技术还可以应用于其他矩阵运算,如矩阵分解和特征值计算等。
矩阵分解是将一个矩阵分解成多个部分矩阵的过程,常见的矩阵分解包括LU分解、QR分解和SVD分解。
这些分解可以帮助我们更好地理解和处理复杂的数学问题。
而特征值计算则是计算一个矩阵的特征值和特征向量,对于解决线性方程组和优化问题都具有重要意义。
随着科学技术的不断发展,超级计算技术中的并行算法和矩阵运算也在不断演进。
首先,随着计算单元和存储器的不断增加,我们可以使用更大规模的矩阵进行计算,从而解决更加复杂的科学问题。
其次,新的并行算法和矩阵运算技术的提出,使得超级计算机能够更快速地处理大规模数据,实现更高效的计算。
最后,超级计算技术的发展也推动了云计算和人工智能等领域的进步,使得计算资源得到充分利用。
【DOC】-矩阵相乘的并行算法的设计与实现矩阵相乘的并行算法的设计与实现仲恺农业工程学院实验报告纸计算机科学与工程学院(院、系) 网络工程专业 083 班组并行计算应用试验课实验三矩阵相乘的并行算法的设计与实现一、实验目的理解和掌握矩阵相乘的并行算法的设计思想以及实现原理二、实验内容编译和运行一个两矩阵相乘算法的并行程序三、实验步骤1 使用vi编辑器输入并行计算的代码,保存在multi.c中#include <stdio.h>#include "mpi.h"#define NRA 62#define NCA 15#define NCB 7#define MASTER 0#define FROM_MASTER 1#define FROM_WORKER 2MPI_Status status;int main(int argc, char *argv[]){int numtasks,taskid,numworkers,source,dest,nbytes,mtype,intsize,dbsize,rows,averow,extra,offset,i,j,k,count;double a[NRA][NCA],b[NCA][NCB],c[NRA][NCB];intsize = sizeof(int);dbsize = sizeof(double);第 1 页共 7 页MPI_Init(&argc,&argv); MPI_Comm_rank(MPI_COMM_WORLD,&taskid);MPI_Comm_size(MPI_COMM_WORLD,&numtasks); numworkers = numtasks-1;if(taskid==MASTER) { printf("Number of worker tasks= %d\n",numworkers); for(i=0;i<NRA;i++) for(j=0;j<NCA;j++)a[i][j]=i+j; for(i=0;i<NCA;i++) for(j=0;j<NCB;j++) b[i][j]=i*j;averow=NRA/numworkers; extra=NRA%numworkers; offset=0; mtype=FROM_MASTER;for(dest=1;dest<=numworkers;dest++) { rows=(dest<=extra)?averow+1:averow; printf("sending %d rows to task %d\n",rows,dest);MPI_Send(&offset,1,MPI_INT,dest,mtype,MPI_COMM_WORLD);MPI_Send(&rows,1,MPI_INT,dest,mtype,MPI_COMM_WORLD); count=rows*NCA;MPI_Send(&a[offset][0],count,MPI_DOUBLE,dest,mtype,MPI_COMM_WORLD); count=NCA*NCB;MPI_Send(&b,count,MPI_DOUBLE,dest,mtype,MPI_COMM_WORLD);offset=offset+rows; } mtype=FROM_WORKER; for(i=1;i<=numworkers;i++){ source = i;MPI_Recv(&offset,1,MPI_INT,source,mtype,MPI_COMM_WORLD,&status);MPI_Recv(&rows,1,MPI_INT,source,mtype,MPI_COMM_WORLD,&status);count=rows*NCB;MPI_Recv(&c[offset][0],count,MPI_DOUBLE,source,mtype,MPI_COMM_WORLD,&status); } printf("Here is the result matrix\n"); for(i=0;i<NRA;i++) { printf("\n"); for(j=0;j<NCB;j++) printf("%6.2f ",c[i][j]); }printf("\n"); } 第 2 页共 7 页if(taskid>MASTER) {mtype=FROM_MASTER;source=MASTER;printf("Master=%d,mtype=%d\n",source,mtype);MPI_Recv(&offset,1,MPI_INT,source,mtype,MPI_COMM_WORLD,&status);printf("offset=%d\n",offset);MPI_Recv(&rows,1,MPI_INT,source,mtype,MPI_COMM_WORLD,&status);printf("rows=%d\n",rows);count=rows*NCA;MPI_Recv(&a,count,MPI_DOUBLE,source,mtype,MPI_COMM_WORLD,&status); printf("a[0][0]=%e\n",a[0][0]);count=NCA*NCB;MPI_Recv(&b,count,MPI_DOUBLE,source,mtype,MPI_COMM_WORLD,&status); printf("b=\n");for(k=0;k<NCB;k++)for(i=0;i<rows;i++) {c[i][k]=0.0;for(j=0;j<NCA;j++)c[i][k]=c[i][k]+a[i][j]*b[j][k];}mtype=FROM_WORKER;printf("after computer\n");MPI_Send(&offset,1,MPI_INT,MASTER,mtype,MPI_COMM_WORLD);MPI_Send(&rows,1,MPI_INT,MASTER,mtype,MPI_COMM_WORLD);MPI_Send(&c,rows*NCB,MPI_DOUBLE,MASTER,mtype,MPI_COMM_WORLD); printf("after send\n");}MPI_Finalize();return 0;}2 编译multi.cmpicc –o multi.o multi.c3 启动mpd后台程序mpd&4 在单机上运行multi.ompirun –np 10 ./multi.o5 在多台计算机上运行multi.o(1) 编辑并行计算的主机文件nodelistnode1:5node2:4node3:8(2) 运行并行计算程序mpirun -machinefile nodelist -np 2 ./multi.o 四、实验结果第 3 页共 7 页Master=0,mtype=1Master=0,mtype=1Number of worker tasks = 9sending 7 rows to task 1sending 7 rows to task 2sending 7 rows to task 3sending 7 rows to task 4sending 7 rows to task 5sending 7 rows to task 6sending 7 rows to task 7sending 7 rows to task 8sending 6 rows to task 9 Master=0,mtype=1offset=0rows=7a[0][0]=0.000000e+00b=after computerafter sendMaster=0,mtype=1offset=7rows=7a[0][0]=7.000000e+00b=after computerafter sendMaster=0,mtype=1offset=14rows=7a[0][0]=1.400000e+01b=after computerafter sendMaster=0,mtype=1offset=28rows=7a[0][0]=2.800000e+01 b=after computerafter sendMaster=0,mtype=1 offset=56rows=6第 4 页共 7 页b=after computerafter sendMaster=0,mtype=1 offset=21rows=7a[0][0]=2.100000e+01 b=after computerafter sendMaster=0,mtype=1 offset=49rows=7a[0][0]=4.900000e+01 b=after computerafter sendoffset=35rows=7a[0][0]=3.500000e+01b=after computerafter sendoffset=42rows=7a[0][0]=4.200000e+01b=after computerafter sendHere is the result matrix 第 5 页共 7 页第 6 页共 7 页双机运行的结果:Number of worker tasks = 1sending 62 rows to task 1Master=0,mtype=1offset=0rows=62a[0][0]=0.000000e+00b=after computerafter sendHere is the result matrix计算出来的矩阵与单机的相同五、实验心得本次实验是通过程序生成两个静态的矩阵,然后计算出两个矩阵的乘机。
行列块不同划分机制下矩阵向量相乘的并行计算方法作者:贺雨晴张楠李云东来源:《电脑知识与技术》2015年第20期摘要:矩阵运算是工程数值计算中一种常见的运算方式。
大量的高维矩阵运算对数学计算提出了新的要求。
该文提出了三种模式下的矩阵划分并行计算,分别是按行,按列,按块划分。
运用MPI并行计算技术,比较出了适合工程上计算的模式,得到了按行划分算法的优势。
关键词:划分,矩阵运算,并行,MPI中图分类号:TP393 文献标识码:A 文章编号:1009-3044(2015)20-0164-04Parallel Computing Method of Matrix-vector Multiplication with Different Partition for Line,Column and BlockHE Yu-qing, ZHANG Nan, LI Yun-dong(China University of Petroleum(East China), Qingdao 266580, China)Abstract: Matrix operation is a common numerical methods in engineering.The high dimension matrix raise a claim for mathematics. There be three modes by which matrix is divided . according to the column, the block line. Using the MPI parallel computing technology, the classification algorithm of line edge is suitable for engineering calculation comparison with model.Key words: divide; matrix multiplication; parallel; MPI1 概述1.1 并行计算简介并行计算(Parallel Computing)是指同时使用多种计算资源解决计算问题的过程,是提高计算机系统计算速度和处理能力的一种有效手段。
矩阵相乘-并行算法并行处理技术课程设计分析报告课程设计题目矩阵相乘并行算法设计姓名廖杰学号M201372880专业计算机技术任课教师金海石宣化所在学院计算机科学与技术学院报告提交日期2014-01-13行度。
对于一个n×n的方阵,棋盘划分最多可以使用n^2个处理器进行并行计算,但使用按行或列分解最多可以使用n个。
对矩阵相乘采用棋盘式划分的算法通常称作Cannon算法。
A)行列划分又叫带状划分(Striped Partitioning),就是将矩阵整行或者整列分成若干个组,每个组指派给一个处理器。
下图所例为4个CPU,8×8矩阵的带状划分。
在带状划分情况下,每个CPU将会均匀分配到2行(列)数据。
8×8矩阵变成了一个1×4或4×1的分块矩阵,每个CPU所属的分块矩阵大小为8×2或2×8。
B)棋盘划分就是将矩阵分成若干个子矩阵,每个子矩阵指派给一个处理器,此时任一处理器均不包含整行或者整列。
下图所示即为4个处理器情况下8×8矩阵的棋盘划分,其中处理器阵列为2×2,每个处理器分配到的子矩阵大小为4×4。
矩阵划分成棋盘状可以和处理器连成二维网孔相对应。
对于一个n×n维矩阵和p×p的二维处理器阵列,每个处理器均匀分配有(n/p)×(n/p)=n^2/p^2个元素。
使用棋盘式划分的矩阵相乘算法一般有两种,Cannon算法和Summa算法。
SUMMA算法能够计算m*l的A矩阵和l*n的B矩阵相乘(m、l、n可不相等),而cannon算法只能实现n*n的A矩阵和n*n的B矩阵相乘,具有很大的局限性。
3.2、算法原理A) 行划分法假设是M*N,计算前,将矩阵N发送给所有从进程,然后将矩阵M分块,将M中数据按行分给各从进程,在从进程中计算M中部分行数据和N的乘积,最后将结果发送给主进程。
基于windowsapi的矩阵相乘并行算法设计随着计算机技术的快速发展,矩阵相乘作为并行计算中的一项重要应用,对于提高计算效率具有重要意义。
本文将基于Windows API设计一种矩阵相乘的并行算法,旨在充分利用多核处理器的能力,提高矩阵相乘的计算速度。
一、引言矩阵相乘是指将一个矩阵的每一行分别与另一个矩阵的每一列相乘,然后将所有结果相加得到结果矩阵。
对于大规模矩阵相乘问题,传统的方法往往需要耗费大量的时间和计算资源。
因此,设计一种高效的并行算法显得尤为重要。
二、算法设计1. 准备工作:首先,我们需要使用Windows API中的相关函数,如CreateThread、GlobalAlloc等,创建一个多线程环境,分配内存空间等。
2. 分配线程:根据系统的核心数量,创建相应数量的线程。
每个线程负责处理矩阵的一部分,实现并行处理。
3. 矩阵传输:通过共享内存或消息传递等方式,将需要相乘的两个矩阵传递给各个线程。
4. 矩阵相乘:每个线程接收到矩阵后,开始进行矩阵相乘的计算。
可以使用Windows API中的数学函数来实现矩阵乘法运算。
5. 结果合并:各个线程计算完成后,将结果合并成一个完整的矩阵。
可以使用Windows API中的同步机制(如Event、Mutex等)来保证线程安全。
6. 清理工作:最后,需要释放资源,关闭线程等。
三、实现细节1. 考虑到Windows API中线程的创建和管理较为复杂,建议使用C++等语言来编写代码,以便更好地利用Windows API提供的函数和类。
2. 在实现过程中,需要注意线程安全和数据一致性问题。
可以使用锁机制(如互斥量、信号量等)来保证同一时间只有一个线程在修改共享数据。
3. 对于大规模矩阵相乘问题,可以考虑使用稀疏矩阵压缩技术,以减少内存占用和提高计算效率。
4. 可以根据实际情况,对算法进行优化,如选择合适的矩阵分割策略、调整线程数量等。
四、性能评估完成算法设计并实现后,可以通过一些性能指标来评估算法的效率。
一种矩阵相乘的并行算法实现与性能评测苑野;于永澔【摘要】With traditional serial algorithm for matrix multiplication , the result will be con-strained by matrix scale , CPU frequency , and memory size and storage space .The most ef-fective way to solve the limitation was parallel algorithm .Therefore, this paper completed the matrix multiplication with SPMD model and MPI in cluster computing environment .Experi-mental results showed that this algorithm under a certain size of the matrix has a good speed-up and efficiency .%用传统的串行算法进行矩阵相乘运算会受到矩阵规模、单机的CPU主频、内存大小和存储器空间等方面的限制。
而使用并行算法是解决上述限制的最有效途径。
为此,在集群计算环境下,使用SPMD计算模型和基于MPI消息传递技术设计实现了矩阵相乘的并行算法。
实验表明,此并行算法在一定矩阵规模下具有较好的加速比和并行效率。
【期刊名称】《哈尔滨商业大学学报(自然科学版)》【年(卷),期】2014(000)005【总页数】4页(P604-607)【关键词】矩阵相乘;消息传递接口;加速比;并行效率【作者】苑野;于永澔【作者单位】哈尔滨工业大学基础与交叉科学研究院,哈尔滨150080;哈尔滨工业大学基础与交叉科学研究院,哈尔滨150080【正文语种】中文【中图分类】TP319随着多核处理器技术、高速网络和分布式计算技术的发展,集群系统已经成为高性能计算领域最重要的计算平台[1].集群系统具有性能价格比高、可扩展性好、高可用性、高利用率和易用性好等特点.MPI(Message Passing Interface)[2]是面向并行编程环境下的一种基于消息传递的标准函数库,被广泛应用于分布式存储的可扩展的并行计算机(Scalable Parallel Computers)和工作站集群(Networks of Workstations).MPI具有较高的通信性能、程序可移植性好、可扩展性好、程序代码实现灵活及高效统一的编程环境等特点.由于集群系统具有典型的分布式存储特征,因此MPI编程模型已经成为目前集群系统上主流的并行程序设计环境.矩阵计算主要应用于科学与工程计算领域,是科学计算的核心问题.而矩阵相乘是矩阵计算最基本的运算.用传统的串行算法库进行矩阵相乘运算[3-4]会受到矩阵规模、单机硬件性能(CPU速度、内存大小、存储器空间)等方面的限制.对串行算法进行并行化处理,使其达到更高的运算性能,是解决上述限制的最有效途径.人们采用了各种方法对矩阵相乘进行并行化处理,并取得了一定的进展,主要包括基于顺序矩阵直接相乘算法(行列划分方法)、基于递归实现的块矩阵相乘方法、基于二维网格实现的矩阵相乘算法(Cannon算法、脉动阵列算法)和Strassen算法等.行列划分算法是经典的矩阵相乘算法中的一种,以其并行时间复杂性优良、代码简单且易于实现等优势使该方法备受研究者的重视.本文在集群环境下,使用SPMD计算模型及MPI消息传递技术对矩阵相乘的行列划分方法进行了并行化算法实现,并定量的对该并行算法的性能进行了测试,实验表明此并行算法在一定矩阵规模下具有较好的加速性能及效率,优于传统的串行算法.1 MPI编程技术MPI是一种消息传递编程模型[5],并已经成为这种编程模型事实上的标准.它不是一种编程语言,而是一个并行函数库.MPI标准函数库为C语言和FORTRAN语言提供了通用的并行程序编程接口.一个MPI系统通常由一组函数库、头文件和相应的运行、调试环境组成.MPI并行程序通过调用MPI库中的函数来完成消息传递. 1.1 MPI基本概念1.1.1 进程组(process group)MPI程序全部进程集合的一个有序子集.进程组中的进程被赋予一个惟一的序号(rank),用于标识该进程.1.1.2 通信器(communicator)由一个进程组和一个标识构成.在该进程组中,进程间可以相互通信.MPI程序中的所有通信必须在通信器中进行.默认的通信器是MPI_COMM_WORLD,所有启动的MPI进程通过调用函数MPI_Init()包含在通信器中,每个进程通过函数MPI_Comm_size()获取通信器中的初始MPI进程个数.通信器可分为在同一进程组内通信的域内通信器和在不同进程组进程间通信的域间通信器.1.1.3 进程序号(rank)MPI程序中用于标识进程组或通信器中一个进程的唯一编号,同一个进程在不同的进程组或通信器中可以有不同的序号.MPI_PROC_NULL代表空进程.1.1.4 消息(message)包括数据(data)和信封(envelope)两部分.数据包含用户将要传递的内容,信封由接收进程序号/发送进程序号、消息标号和通信器三部分组成.消息被封装在“信封”中,然后经缓冲区向网络传输层打包发送.1.1.5 MPI对象MPI系统内部定义的数据结构,包括数据类型、通信器(MPI_Comm)、通信请求(MPI_Request)等,它们对用户不透明.1.1.6 MPI连接器(handles)连接MPI对象的具体变量,用户可以通过它访问和参与相应的MPI对象的具体操作.1.2 点对点通信点对点通信是指在一对进程之间进行的消息收发操作,是MPI中最基本的通信模式.MPI提供阻塞型(blocking)和非阻塞型(non blocking)两种类型的点对点通信函数.阻塞型函数是指一个例程需等待操作完成才返回,返回后用户可以重新使用调用中所占用的资源.非阻塞型函数是指一个例程不必等待操作完成便可以返回,返回后用户不可重用所占用的资源.根据以上两类通信函数的不同特点,MPI提供了四种不同的通信模式,分别是标准模式(standard mode)、缓冲模式(buffered mode)、同步模式(synchronous mode)和就绪模式(ready mode).1.3 聚合通信聚合通信是指在一个通信器内的所有进程同时调用同一个聚合通信函数而进行的通信.聚合通信包括障碍同步(MPI_Barrier)、广播(MPI_Bcast)、数据收集(MPI_Gather)、数据发散(MPI_Scatter)、数据转置(MPI_Alltoall)和规约(MPI_Reduce).2 矩阵乘法并行算法集群上矩阵乘法并行算法采用了行列划分方法、SPMD计算模型和基于MPI消息传递的并行处理技术.假设A为m*k阶矩阵,B为k*n阶矩阵,C为m*n阶矩阵,计算问题C=A*B.令m=m`*p、n=n`*p,矩阵A=[A0t A1t …Ap-1t],矩阵B=[B0 B1 …Bp-1],矩阵A第i行的每个元素与矩阵B第j列的各元素分别相乘,并将乘积相加到矩阵C的第i行第j列的一个元素Ci,j,此时C=(Ci,j)=(AiBj).将j=0,1…,p-1存放在Pi中,使用p个处理机,每次每个处理机计算出一个Ci,j,需要p次完成.具体算法[6-7]如下:beginMp1≡myid+1 mod p,mm1≡myid-1 mod pfor i=0 to p-1 dol≡i+myid mod pCl=ABIf i≠p-1,send(B,mm1),recv(B,mp1)endforendfor在p=n2个处理器进行n*n矩阵乘法时,并行时间的复杂性为O(n).广播算法决定通信开销进而支配通信时间,n*n矩阵通过独立的消息分发到n2个从处理器上,每个从处理器向主处理器返回C的一个元素.其通信时间tcomm=n2(2tstartup+(2n+1)tdata),其中tstartup是数据传送的延迟或启动时间,tdata是数据传输返回时间[8].3 实验验证本文的硬件测试环境是8个节点组成的集群系统,采用Infiniband高速网络互联,每个节点配有1颗Intel Xeon 2.5 G处理器,32 G内存,1 T SAS磁盘,GPFS共享文件系统,软件环境是Red Hat Linux操作系统,编译器为Intel C++13.0.1,MPI的版本为Intel MPI 4.1.加速比和效率是衡量多处理机和单处理机系统相对性能的重要指标.把串行应用程序在单处理机上的执行时间和该程序并行化后在多处理机上的执行时间的比值定义为加速比,它是并行算法可扩展性的重要参数.将加速比与CPU个数之间的比值定义为效率,它反映了在某一时间段内,一个处理器真正用于计算的时间.设矩阵大小分别为1 200×1 200、4 000×4 000,8 000×8 000,各做5次实验,将5次计算时间的平均值作为执行时间.表1为单处理机系统的串行程序执行时间.表2为多处理机系统的并行程序执行时间.图1为矩阵并行程序运行时间变化.图2为不同矩阵规模下运行时间比较.表1 单处理机的串行执行时间矩阵大小串行执行时间1 200×1 2000.411 1214 000×4 0001.124 6448 000×8 0003.280 423表2 多处理机并行程序执行时间矩阵大小并行执行时间 2 节点 4 节点 8 节点1 200×1 200 0.244 172 0.147 231 0.276 6124 000×4 000 0.579 226 1.100 790 0.592 2958000×8 000 2.228 761 1.129 427 0.576 136图1 矩阵并行程序运行时间图2 不同矩阵规模下运行时间比较如图1所示,可以看到在所有矩阵的多节点测试中,并行程序的运行时间随着矩阵规模不断变大时,其运行时间基本保持不断的增加.然而在节点较多(如node=8时)的并行环境下运行时,其并行程序运行时间随矩阵规模变化不明显.如在矩阵为4 000×4 000、8 000×8 000下,运行时间基本保持不变.这主要是因为在程序的执行时间中,绝大部分的时间用于数据的通信而非用于真正的计算.由图2可知,在矩阵规模很大时(当矩阵为8 000×8 000),其运行时间随着节点数的增加而不断减少.其原因是用于计算的时间占了绝大部分,数据通信时间大量减少,并行计算的优势得到了体现.表3为多处理机并行算法的加速比和效率.图3为不同矩阵规模下加速比比较,图4为不同矩阵规模下并行效率比较.图5为矩阵规模在8 000阶下的加速比.表3 多处理机并行算法的加速比和效率矩阵大小 2 节点 4 节点 8 节点加速比效率加速比效率加速比效率1 200×12001.680.842.790.701.480.194 000×4 0001.940.971.020.261.900.248 000×8 0001.470.742.900.735.690.71图3 不同矩阵规模下加速比比较图4 不同矩阵规模下并行效率比较图5 矩阵规模在8 000阶下的加速比如图3~5可知,该并行算法的在不同矩阵规模下,其加速比均大于1,这说明此算法与传统的串行算法相比具有较高的加速性能.当矩阵规模较小时(如矩阵为1 200×1 200时),其加速比随着节点数的增加表现为先迅速变大,然后逐渐变小.并行效率呈现逐渐下降的趋势.在node=4时获得最大加速比2.79,此时的效率为70%.当矩阵的规模较大时(如矩阵为8 000×8 000),其加速比几乎表现为线性增加,在node=8时获得最大加速比5.69,而并行效率几乎保持不变,基本维持的在72%左右.这说明此种并行算法在矩阵规模较大的条件下,加速效果明显,效率较高.4 结语本文对集群计算环境下矩阵相乘问题应用SPMD计算模型和基于MPI消息传递技术实现了其并行算法,并通过实验验证了该算法的有效性.与传统的串行算法相比,结果证明此算法在一定的矩阵规模下具有较好的加速性能及效率.参考文献:[1] CHAI L, LAI P, JIN H, et al. Designing an efficient kernel-level and user-level hybrid approach for mpi intra-node communication on muti-core systems[C]//ICPP’08:Proceedings of the 2008 37th International Conference on Parallel Processing,Washington DC: IEEE Computer Society, 2008.[2] MPI: A Message-Passing Interface Standard[S].[3] BLACKFORD L S, DEMMEL J, J DONGARRA, et al. An update set of basic linear algebra subprograms(BLAS)[J]. ACM Transactions on Mathematical Software,2002, 28(2): 135-151.[4] COHN H, KLEINBERG R, SZEGEDY B, et al. Group-theoretic algorithms for matrix multiplication[C]//Proceedings of the 46th Annual Symposium on Foundations of Computer Science, 23-25 ,2005.[5] MCQUILLAN J M, D WALDEN C. Some considerations for a high performance message-based interprocess communication system [J]. SIGOPS Oper.Syst.Rev., 1975, 9: 77-86.[6] 张林波, 迟学斌. 并行算法导论[M]. 北京: 清华大学出版社,2006.[7] 陆鑫达. 并行程序设计[M]. 北京: 机械工业出版社, 2006.[8] 徐红波,胡文,潘海为,等.高维空间范围查询并行算法研究[J].哈尔滨商业大学学报:自然科学版,2013,29(1):73-75,111.。
矩阵相乘并行实现1、算法描述:设有如下矩阵相乘:C=A×B其中A,B分别是m×k和k×n矩阵,C是m×n矩阵。
若处理器个数为p,且它们的编号依次是0,1,…,p-1,则设可将矩阵A、B、C分成p个大小为mxm的子块,其中A=(Aij)m×m ,B=(Bij)m×m,和C=(Cij)m×m,其中A¬ij,Bij和Cij是n×n矩阵。
同时假设和。
定义对角块矩阵,则其中,。
利用此关系式,将节点编号从一维映射到二维,数据,,存放在中,可得到下面的在处理机结点上的算法。
该算法数据交量算法流程如下:流程图如下所示:2、程序代码:#include <stdlib.h>#include <string.h>#include <mpi.h>#include <time.h>#include <stdio.h>#include <math.h>float **A, **B, **C;float *a, *b, *c, *tmp_a, *tmp_b;int dg=1000, dl, dl2,p, sp;int my_rank, my_row, my_col;MPI_Status status;int get_index(int row, int col, int sp){return ((row+sp)%sp)*sp + (col+sp)%sp; }void random_A_B(){int i,j;srand((unsigned int)time(NULL));for(i=0; i<dg ; i++)for(j=0; j<dg ; j++){A[i][j] = rand();B[i][j] = rand();C[i][j] = 0.0;}}void scatter_A_B(){int i,j,k,l;int p_imin,p_imax,p_jmin,p_jmax;for(k=0; k<p; k++){p_jmin = (k % sp ) * dl;p_jmax = (k % sp + 1) * dl-1;p_imin = (k - (k % sp))/sp * dl;p_imax = ((k - (k % sp))/sp +1) *dl -1;l = 0;for(i=p_imin; i<=p_imax; i++){for(j=p_jmin; j<=p_jmax; j++){tmp_a[l] = A[i][j];tmp_b[l] = B[i][j];l++;}}if(k==0){memcpy(a, tmp_a, dl2 * sizeof(float));memcpy(b, tmp_b, dl2 * sizeof(float));} else{MPI_Send(tmp_a, dl2, MPI_FLOAT, k, 1, MPI_COMM_WORLD);MPI_Send(tmp_b, dl2, MPI_FLOAT, k, 2, MPI_COMM_WORLD);}}}void init_alignment(){MPI_Sendrecv(a, dl2, MPI_FLOAT, get_index(my_row,my_col-my_row,sp), 1,tmp_a, dl2, MPI_FLOAT, get_index(my_row,my_col+my_row,sp), 1,MPI_COMM_WORLD, &status);memcpy(a, tmp_a, dl2 * sizeof(float) );MPI_Sendrecv(b, dl2, MPI_FLOAT, get_index(my_row-my_col,my_col,sp), 1,tmp_b, dl2, MPI_FLOAT, get_index(my_row+my_col,my_col,sp), 1,MPI_COMM_WORLD, &status);memcpy(b, tmp_b, dl2 * sizeof(float) );}void main_shift(){int i,j,k,l;for(l=0; l<sp; l++){for(i=0; i<dl; i++)for(j=0; j<dl; j++)for(k=0; k<dl; k++)c[i*dl+j] += a[i*dl+k]*b[k*dl+j];MPI_Send(a , dl2, MPI_FLOAT, get_index(my_row, my_col-1, sp), 1, MPI_COMM_WORLD);MPI_Recv(a , dl2, MPI_FLOAT, get_index(my_row, my_col+1, sp), 1, MPI_COMM_WORLD, &status);MPI_Send(b , dl2, MPI_FLOAT, get_index(my_row-1, my_col, sp), 1, MPI_COMM_WORLD);MPI_Recv(b , dl2, MPI_FLOAT, get_index(my_row+1, my_col, sp), 1, MPI_COMM_WORLD, &status);}}void collect_C(){int i,j,i2,j2,k;int p_imin,p_imax,p_jmin,p_jmax;for (i=0;i<dl;i++)for(j=0;j<dl;j++)C[i][j]=c[i*dl+j];for (k=1;k<p;k++){MPI_Recv(c, dl2, MPI_FLOAT, k, 1, MPI_COMM_WORLD, &status);p_jmin = (k % sp ) *dl;p_jmax = (k % sp + 1) *dl-1;p_imin = (k - (k % sp))/sp *dl;p_imax = ((k - (k % sp))/sp +1) *dl -1;i2=0;for(i=p_imin; i<=p_imax; i++){j2=0;for(j=p_jmin; j<=p_jmax; j++){C[i][j]=c[i2*dl+j2];j2++;}i2++;}}}void print(float **m,char *str){int i,j;printf("%s",str);for(i=0;i<dg;i++){for(j=0;j<dg;j++)printf("%15.0f ",m[i][j]);printf("\n");}printf("\n");}int main(int argc, char *argv[]){int i;MPI_Init(&argc, &argv);MPI_Comm_size(MPI_COMM_WORLD, &p);MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);sp = sqrt(p);if (sp*sp != p){if (my_rank == 0)printf("Number of processors is not a quadratic number!\n");MPI_Finalize();exit(1);}if (argc != 2){if (my_rank == 0)printf("usage: mpirun -np ProcNum cannon MatrixDimension\n");MPI_Finalize();exit(1);}dg = atoi(argv[1]);dl = dg / sp;dl2 = dl * dl;my_col = my_rank % sp ;my_row = (my_rank-my_col) / sp ;a = (float *)malloc( dl2 * sizeof(float) );b = (float *)malloc( dl2 * sizeof(float) );c = (float *)malloc( dl2 * sizeof(float) );for(i=0; i<dl2 ; i++)c[i] = 0.0;tmp_a = (float *)malloc( dl2 * sizeof(float) );tmp_b = (float *)malloc( dl2 * sizeof(float) );if (my_rank == 0){A = (float **)malloc( dg * sizeof(float*) );B = (float **)malloc( dg * sizeof(float*) );C = (float **)malloc( dg * sizeof(float*) );for(i=0; i<dg; i++){A[i] = (float *)malloc( dg * sizeof(float) );B[i] = (float *)malloc( dg * sizeof(float) );C[i] = (float *)malloc( dg * sizeof(float) );}random_A_B();scatter_A_B();} else{MPI_Recv(a, dl2, MPI_FLOAT, 0 , 1, MPI_COMM_WORLD, &status);MPI_Recv(b, dl2, MPI_FLOAT, 0 , 2, MPI_COMM_WORLD, &status);}init_alignment();main_shift();if(my_rank == 0){collect_C();print(A,"random matrix A : \n");print(B,"random matrix B : \n");print(C,"Matrix C = A * B : \n");} else{MPI_Send(c,dl2,MPI_FLOAT,0,1,MPI_COMM_WORLD);}MPI_Barrier(MPI_COMM_WORLD);MPI_Finalize();return 0;}。
两个100-100阶矩阵相乘的并行程序两个100*100阶矩阵相乘的并行程序【摘要】对于100*100阶以上的矩阵乘积运算,构造一种适用于多处理机系统的并行算法。
此算法能很大程度上提高计算机的效率和速度,并同时给出了详细的运算程序和结果。
【关键词】并行算法;矩阵乘积在很多的工程问题的计算中,会常遇到一些有关大型的高阶矩阵的计算,尤其是两矩阵相乘最为常见。
当遇到高阶矩阵时,计算过程需要占用较多的工作资源和较大的计算机内存,计算效率受到影响。
随着大型的具有多处理机的并行计算机系统的发展,一些大型计算可以构造相应的并行计算方法进行并行处理,从而减少计算机的工作单元,提高计算效率、节约资源。
因此,对于矩阵的乘积和方阵求逆运算本文构造了一种并行算法,并给出了相应的实现方法。
1.矩阵乘法的并行算法设A是一个M*100矩阵,B是一个100*N矩阵,记C=AB,M=N=100。
又设有一个主机系统具有p台处理机。
我们为建立在p台处理机下求解C=AB的并行算法。
首先将矩阵A和B分块,每个矩阵分成体积相近的p块,如下:A=(AT1,AT2,…ATp)T,B=(B1,B2,…,Bp)其中Ai为Mi×100矩阵,Bi为100×Ni矩阵,i=1,2,…,p,ΣMi=M,ΣNi=N。
则:从C的结构可以看出,C是由P2个低阶矩阵乘积所组成。
当A,B分块一定时,每个低阶矩阵乘积是独立的,可以并行计算。
为了表述简单,不妨设m,n均可被p整除,即A,B可均匀地分为p块,并记mi=mp=mp,ni=np=np,i=1,2,…p。
至此,我们来实现上述乘积运算的并行算法。
step 1:将Ai,Bi分别存入处理机i(i=1,2,…,p)的矩阵A1,B1中,其中A1为mp×100矩阵,B1为100×np为矩阵,并令k=1。
step 2:信息轮换传送。
处理机i将B1中元素传送到第i+1台处理机(i=1,2,…,p-1);第p台处理机将B1中元素传送到第1 台处理机。
并行处理技术课程设计分析报告课程设计题目矩阵相乘并行算法设计姓名廖杰学号M*********专业计算机技术任课教师金海石宣化所在学院计算机科学与技术学院报告提交日期2014-01-13一、实验目的1、学习使用集群;2、掌握并行处理或分布计算的编程方法;3、学会以并行处理的思想分析问题。
二、实验要求1、自行生成矩阵作为算法的输入;2、使用并行处理技术编程,例如:MPI、OpenMP、MR;3、矩阵大小至少为1000*1000;4、加速比越大成绩越高。
三、实验内容3.1、矩阵的划分:对于矩阵相乘的并行算法,可以有三种:对矩阵按行划分、按列划分和棋盘式分块划分。
和按行或列划分相比,棋盘式划分可以开发出更高的并行度。
对于一个n×n的方阵,棋盘划分最多可以使用n^2个处理器进行并行计算,但使用按行或列分解最多可以使用n个。
对矩阵相乘采用棋盘式划分的算法通常称作Cannon算法。
A)行列划分又叫带状划分(Striped Partitioning),就是将矩阵整行或者整列分成若干个组,每个组指派给一个处理器。
下图所例为4个CPU,8×8矩阵的带状划分。
在带状划分情况下,每个CPU将会均匀分配到2行(列)数据。
8×8矩阵变成了一个1×4或4×1的分块矩阵,每个CPU所属的分块矩阵大小为8×2或2×8。
B)棋盘划分就是将矩阵分成若干个子矩阵,每个子矩阵指派给一个处理器,此时任一处理器均不包含整行或者整列。
下图所示即为4个处理器情况下8×8矩阵的棋盘划分,其中处理器阵列为2×2,每个处理器分配到的子矩阵大小为4×4。
矩阵划分成棋盘状可以和处理器连成二维网孔相对应。
对于一个n×n维矩阵和p×p的二维处理器阵列,每个处理器均匀分配有(n/p)×(n/p)=n^2/p^2个元素。
使用棋盘式划分的矩阵相乘算法一般有两种,Cannon算法和Summa算法。
SUMMA算法能够计算m*l的A矩阵和l*n的B矩阵相乘(m、l、n可不相等),而cannon算法只能实现n*n的A矩阵和n*n 的B矩阵相乘,具有很大的局限性。
3.2、算法原理A) 行划分法假设是M*N,计算前,将矩阵N发送给所有从进程,然后将矩阵M分块,将M中数据按行分给各从进程,在从进程中计算M中部分行数据和N的乘积,最后将结果发送给主进程。
这里为了方便,有多少进程,就将M分了多少块,除最后一块外的其他数据块大小都相等,最后一块是剩下的数据,大小大于等于其他数据块大小,因为矩阵行数不一定整除进程数。
最后一块数据在主进程中计算,其他的在从进程中计算。
定义两个矩阵M和N,N所有进程都需要,M可以只在主进程中定义。
其他的变量视主进程和从进程需要按要求定义在合适的位置。
代码参见附录部分。
B) Cannon算法Cannon算法的基本思想可以如下表示:假设两个矩阵A和B相乘,把A和B矩阵划分成p 个方块,进程的编号从到,并在最初把子矩阵和分配给。
虽然第i行的每个进程需要全部的个子矩阵,但我们还是能调度第i行个进程的计算,使得每个进程在任何时刻都是用不同的。
每完成一次矩阵乘法,这些块在各进程之间被轮流使用,似的每次轮流之后每个进程都可以得到新的。
对列使用同样的调度,则在任何时刻,任何进程至多拥有每个矩阵的一个块,在所有进程中,改算法需要的总内存量为。
下图为此算法中不同进程上子矩阵乘法的调度过程。
假如矩阵C=A*B,则C的的计算公式如下:进程P 存储分块矩阵这一部分。
块矩阵乘法要计算所有匹配的和,然而只有在主对角线的才是匹配的。
因此需要采用循环移动分块矩阵的方法来使每个进程都有一对可以直接相乘的匹配的块,具体方法如下:(1)将排第i行的块循环左移i个位置,将第列.块循环上移j个位置;(2) 进程执行乘一加运算,然后将移动得到的块循环左移1个位置,将移动得到的块循环上移1个位置;(3)重复第2步(一1)次,每次移动后进程执行乘一加运算。
经过以上操作后就可以得到矩阵C的解。
代码请参见附录部分C) Summa算法SUMMA 算法首先将A , B 和C 划分为相同大小的矩阵,对应放在mesh_r × mesh_c 的二维mesh 上。
但SUMMA 算法将矩阵乘法分解为一系列的秩nb 修正, 即各处理器中的A 和B 分别被分解为nb 大小的列块和行块进行相乘,前面所说的分块尺寸就是指nb 的大小。
算法中, 广播实现为逻辑处理器行环或列环上的流水线传送, 达到了计算与通信的重叠. 具体描述如算法1所示。
C= 0for i= 0 t o k-1 step nb docur col = i×c/ ncur row = i×r / mif my col = cur rol 向本行广播A 从i mod (k/c) 列开始的nb 列, 存于A′if my row = cur row 向本列广播B 从i mod (k/r) 行开始的nb 行, 存于B ′C= A′×B ′end forSUMMA算法的核心思想是:各处理器收集来自同一行处理器中A矩阵子块的所有列和同一列处理器中B矩阵子块的所有行,然后将行列相乘后累加,形成一个C矩阵的分块矩阵。
最后由rank=0的处理器将其他处理器的数据收集起来,形成最终的矩阵C。
SUMMA算法相较于cannon算法的优势只要体现在SUMMA算法能够计算m*l的A矩阵和l*n的B矩阵相乘(m、l、n可不相等),而cannon算法只能实现n*n的A矩阵和n*n 的B矩阵相乘,具有很大的局限性。
代码参见附录部分。
3.3、程序运行结果对比分析A) 统一的实验条件矩阵大小:1000*1000;矩阵数字范围:0~10;矩阵数字分布是否随机:是;分配的进程数:9;B) 实验进程数解释由于Cannon算法本身局限性,要使用Cannon算法,必须满足进程数为整数的平方,比如1、4、9、16等。
在本次的实验环境之下,经过多次对比分析,发现对于分行还是分块算法,进程数安排在8~15可以得到最理想的运行速度:进程数目过小则每个进程单独运算的时间过多,进程数过大则选路时间(进程与进程之间的通信时间)过长。
而对比要求每个算法的进程相同,故此处选择进程数目为9.C) 算法运行时间对比Cannon算法运行时间如下:分行法运行时间如下:串行算法运行时间如下:由于Summa算法与Cannon算法思路几乎相同,而且在算法预处理阶段要比Cannon算法更耗时,故没有做多余的实验。
CANNON显而易见,单纯的运用分行算法所花费的时间是最短的。
D) 结果分析Cannon算法相对于简单的行划分并行处理算法,其优势仅仅在于并行度可以更高(可达到N*N个进程,N为矩阵宽),但在并行度相同的情况下,其多出的预处理过程、矩阵发送与结果回收机制会占用更多的时间。
3.4、程序调优A) 行划分算法优化1. 循环优化在预估计矩阵大小为10的倍数的基础上,对每一个步长为1的循环做处理,改为步长为10的循环,将十次循环体全部压缩在一次循环中,从而大量减少了循环的判别时间,提升循环运算速度。
例如在单个线程在计算部分结果时,采用的循环为:for(i=0;i<line;i++){for(j=0;j<width;j++){DATA temp=0;for(k=0;k<width;k+=10){temp += buffer[i*width+k]*n[j*width+k];temp += buffer[i*width+k+1]*n[j*width+k+1];temp += buffer[i*width+k+2]*n[j*width+k+2];temp += buffer[i*width+k+3]*n[j*width+k+3];temp += buffer[i*width+k+4]*n[j*width+k+4];temp += buffer[i*width+k+5]*n[j*width+k+5];temp += buffer[i*width+k+6]*n[j*width+k+6];temp += buffer[i*width+k+7]*n[j*width+k+7];temp += buffer[i*width+k+8]*n[j*width+k+8];temp += buffer[i*width+k+9]*n[j*width+k+9];}ans[i*width+j] = temp;}}在将循环次数压缩的同时,为了进一步减少循环的运算量,在每一个步长为10的循环之前做预处理,避免循环体中的重复运算。
例如在主进程在接受其他进程时,将结果矩阵整合的过程:for(k=1;k<numprocs;k++){MPI_Recv(ans,line*width,MPI_INT,k,2,MPI_COMM_WORLD,&status);for(i=0;i<line;i++){count=i*k*width; //将i*k*width提前算好,减少了下一步循环的重复运算count1=i*width;for(j=0;j<width;j+=10){p[count+j] = ans[count1+j];p[count+j+1] = ans[count1+j+1];p[count+j+2] = ans[count1+j+2];p[count+j+3] = ans[count1+j+3];p[count+j+4] = ans[count1+j+4];p[count+j+5] = ans[count1+j+5];p[count+j+6] = ans[count1+j+6];p[count+j+7] = ans[count1+j+7];p[count+j+8] = ans[count1+j+8];p[count+j+9] = ans[count1+j+9];}}}2. 节省空间在进行矩阵工作量划分并传送的时候,为每一个进程开辟仅仅是自己所需要大小的空间,例如在9进程的环境下,每个进程所需要接受的缓存空间为B矩阵大小以及大约1/9大小A 矩阵。
内存开辟:buffer = (DATA *)malloc(sizeof(DATA)*width*line);矩阵A分块传输:for(k=1;k<numprocs;k++){for(i=k;i<width;i+=numprocs){count=i/numprocs*width;count1=i*width;for(j=0;j<width;j+=10){buffer[count+j]=m[count1+j];buffer[count+j+1]=m[count1+j+1];buffer[count+j+2]=m[count1+j+2];buffer[count+j+3]=m[count1+j+3];buffer[count+j+4]=m[count1+j+4];buffer[count+j+5]=m[count1+j+5];buffer[count+j+6]=m[count1+j+6];buffer[count+j+7]=m[count1+j+7];buffer[count+j+8]=m[count1+j+8];buffer[count+j+9]=m[count1+j+9];}}MPI_Send(buffer,line*width,MPI_INT,k,1,MPI_COMM_WORLD);同样的方式也运用在运行空间的开辟上。