并行算法实验设计报告
中科大并行程序实验报告

并行程序设计实验报告公共部分1.用MPI_Send、MPI_Recv实现MPI_Bcast、MPI_Alltoall、MPI_Gather、MPI_Scatter 等MPI群及通信函数功能。
_MPI_Bcast:程序运行结果如下伪代码如下:_MPI_Bcast(sendbuf, sendcount, sendtype, root, comm)对每个处理器执行以下算法if my_rank = root thenfor i = 0 to p do //p为进程个数MPI_Send(sendbuf, sendcount, sendtype, i, root, comm) //root向每个进程发送消息end forend if//每个进程从root接收带有root标签的消息,接受信息存在各自的sendbuf中MPI_Recv(sendbuf, sendcount, sendtype, root, root, comm., &status)_MPI_Scatter:将字符串”abcdefgh”以进程2为根散播出去,程序运行结果如下:伪代码如下:_MPI_Scatter(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root, comm)各处理器执行以下算法if my_rank = root thenfor i = 0 to sendcount doMPI_Send(sendbuf + i, 1, sendtype, i , root, comm)//将sendbuf中的信息按进程标识顺序发送给各个进程end forend if//每个进程从root处接收各自的消息,并存在recvbuf中第root号位置MPI_Recv(recvbuf + root, 1, recvtype, root, root, comm., &status)_MPI_Alltoall:进程0到进程5存储的数据分别为”000000”到”555555”,经全局交换之后运行结果如下:伪代码如下:_MPI_Alltoall(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, comm)对每个处理器执行以下代码:for i = 0 to p-1_MPI_Scatter(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, i, comm) //_MPI_Scatter即为前一个程序的伪代码//Alltoall就是每一个进程都以自己为root执行一次Scatterend for_MPI_Gather:将四个进程的第3个字符汇聚到进程2,执行结果如下:伪代码如下:_MPI_Gather(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root, comm) 对每个进程执行以下代码MPI_Send(sendbuf,sendcount, sendtype, root, root, comm)if my_rank = root thenfor i = 0 to p-1 doMPI_Recv(recvbuf + i, recvcount, recvtype, i, root, comm., &status) end forend if2. LU分解的MPI实现(顺序划分)5个节点、处理9x9矩阵时运行结果如下:伪代码如下:输入:矩阵A(nxn)输出:下三角矩阵L(nxn),上三角矩阵U(nxn)Begin对所有处理器my_rank(0..p-1)同时执行如下算法:for i = 0 to m-1 do //对处理器的各行**************for j = 0 to p-1 doif(my_rank = j) thenv = j * m + i; //当前主行************************for k = v to n dof[k] = a[i, k]end forelsev = j*m + i; //当前主行************************接收主行所在处理器广播来的主行元素End ifif(my_rank = j) then //编号为j的处理器对其i+1行以后各行进行变换for k= i+1 to m-1 doa[k, v] = a[k, v] / f[v]for w = v+1 to n-1 doa[k, w] = a[k, w] – f[w]*a[k, v]end forend forif(my_rank > j) then //编号大于j的处理器对其所有行变换for k = 0 to m -1 doa[k, v] = a[k, v] / f[v]for w = v+1 to n-1 doa[k, w] = a[k, w] – f[w]*a[k, v]end forend forend ifend forend forend大体思路如同上面的伪代码给出,核心思想就是如果当前主行在第j号处理器,那么按照顺序划分的想法,编号小于j的处理器已经变换完了自己的各行,不需要做什么处理;编号为j的处理器应用当前主行为其j+1行等后续各行变换;编号大于j的处理器其各行都还没有经过变换,所以应用主行对其所有行进行变换。
并行程序实验报告

并行程序设计实验报告姓名:学号:一、实验目的通过本次试验,了解使用OpenMP编程的基本方法和MPI的编程方法,通过实践实现的基本程序,掌握基本的线程及进程级并行应用开发技术,能够分析并行性能瓶颈及相应优化方法。
二、实验环境Linux操作系统,mpi库,多核处理器三、实验设计与实现(一)MPI并行程序设计用MPI编写一个greeting程序,编号为0的进程接受其它各进程的“问候”,并在计算机屏幕上显示问候情况。
用MPI编写一个多进程求积分的程序,并通过积分的方法求π的值,结果与π的25位精确值比较。
(二)多线程程序设计用Pthreads或OpenMP编写通过积分的方法求π的程序。
把该程序与相应的MPI程序比较。
用Pthreads或OpenMP编写编写矩阵相乘的程序,观察矩阵增大以及线程个数增减时的情形。
四、实验环境安装(一)MPI环境安装1.安装kylin操作系统的虚拟机(用VirtualBox)2.安装增强功能,使之与windows主机能够文件共享。
3.拷贝mpich-3.0.4.tar.gz到/root/myworkspace/目录下,并解压(tar xzf mpich-3.0.4.tar.gz)4.下面开始安装mkdir /root/myworkspace/mpi./configure --prefix=/root/myworkspace/mpi --disable-f77 --disable-fcmakemake install5.配置环境变量打开/root/.bashrc文件,在文件的末尾加上两行:PATH=$PATH:/root/myworkspace/mpi/binexport PATH保存退出,然后执行命令source /root/.bashrc(二)openMP实验环境安装Visual Studio中修改:项目->属性->c/c++->语言,将“OpenMP支持”改成“是”:五、实验结果及分析(一)MPI并行程序设计实验一:问候发送与接收非零号进程将问候的信息发送给0号进程,0号进程依次接收其它进程发送过来的消息并将其输出。
华科并行实验报告

一、实验模块计算机科学与技术二、实验标题并行计算实验三、实验目的1. 了解并行计算的基本概念和原理;2. 掌握并行编程的基本方法;3. 通过实验加深对并行计算的理解。
四、实验环境1. 操作系统:Windows 102. 编程语言:C++3. 并行计算平台:OpenMP五、实验步骤1. 准备实验环境首先,在计算机上安装OpenMP库,并配置环境变量。
2. 编写并行计算程序编写一个简单的并行计算程序,实现以下功能:(1)计算斐波那契数列的第n项;(2)计算素数的个数;(3)计算矩阵乘法。
以下为斐波那契数列的并行计算程序示例:```cpp#include <omp.h>#include <iostream>using namespace std;int main() {int n = 30;int fib[31] = {0};fib[0] = 0;fib[1] = 1;#pragma omp parallel forfor (int i = 2; i <= n; i++) {fib[i] = fib[i - 1] + fib[i - 2];}cout << "斐波那契数列的第" << n << "项为:" << fib[n] << endl; return 0;}```3. 编译程序使用g++编译器编译程序,并添加OpenMP库支持。
```bashg++ -fopenmp -o fib fib.cpp```4. 运行程序在命令行中运行编译后的程序,观察结果。
5. 分析结果通过对比串行计算和并行计算的结果,分析并行计算的优势。
六、实验过程1. 准备实验环境,安装OpenMP库并配置环境变量;2. 编写并行计算程序,实现斐波那契数列的并行计算;3. 编译程序,并添加OpenMP库支持;4. 运行程序,观察结果;5. 分析结果,对比串行计算和并行计算的性能。
并行实验快速排序实验报告完整版

华南师范大学实验报告学生姓名学 号专 业计算机科学与技术年级、班级课程名称并行计算实验项目快速排序的并行算法实验时间 2011 年 6 月 10 日实验类型实验指导老师实验评分3.1实验目的与要求1.熟悉快速排序的串行算法2.熟悉快速排序的并行算法3.实现快速排序的并行算法3.2 实验环境及软件单台或联网的多台PC机, Linux操作系统, MPI系统。
3.3实验内容1.快速排序的基本思想2.单处理机上快速排序算法3.快速排序算法的性能4.快速排序算法并行化5.描述了使用2m个处理器完成对n个输入数据排序的并行算法。
6.在最优的情况下并行算法形成一个高度为logn的排序树7、完成快速排序的并行实现的流程图8、完成快速排序的并行算法的实现3.4实验步骤3.4.1.快速排序(Quick Sort)是一种最基本的排序算法, 它的基本思想是: 在当前无序区R[1, n]中取一个记录作为比较的“基准”(一般取第一个、最后一个或中间位置的元素), 用此基准将当前的无序区R[1, n]划分成左右两个无序的子区R[1, i-1]和R[i, n](1≤i≤n), 且左边的无序子区中记录的所有关键字均小于等于基准的关键字, 右边的无序子区中记录的所有关键字均大于等于基准的关键字;当R[1, i-1]和R[i, n]非空时, 分别对它们重复上述的划分过程, 直到所有的无序子区中的记录均排好序为止。
3.4.2.单处理机上快速排序算法输入: 无序数组data[1,n]输出: 有序数组data[1,n]Begincall procedure quicksort(data,1,n)Endprocedure quicksort(data,i,j)Begin(1) if (i<j) then(1.1)r = partition(data,i,j)(1.2)quicksort(data,i,r-1);(1.3)quicksort(data,r+1,j);end ifEndprocedure partition(data,k,l)Begin(1) pivo=data[l](2) i=k-1(3) for j=k to l-1 doif data[j]≤pivo theni=i+1exchange data[i] and data[j]end ifend for(4) exchange data[i+1] and data[l](5) return i+1End3.4.3.快速排序算法的性能主要决定于输入数组的划分是否均衡, 而这与基准元素的选择密切相关。
并行计算课程设计报告

并行计算与多核多线程技术课程报告专业班级学号XX成绩___________________年月日课程报告要求手写内容:设计目的、意义,设计分析,方案分析,功能模块实现,最终结果分析,设计体会等。
允许打印内容:设计原理图等图形、图片,电路图,源程序。
硬件类的设计,要有最终设计的照片图;软件类设计,要有各个功能模块实现的界面图、输入输出界面图等。
评价理论根底实践效果〔正确度/加速比〕难度工作量独立性目录1. 设计目的、意义〔功能描述〕12. 方案分析〔解决方案〕13. 设计分析13.1 串行算法设计13.2 并行算法设计13.3 理论加速比分析24. 功能模块实现与最终结果分析24.1 基于OpenMP的并行算法实现24.1.1 主要功能模块与实现方法24.1.2 实验加速比分析34.2 基于MPI的并行算法实现34.2.1 主要功能模块与实现方法34.2.2 实验加速比分析44.3 基于Java的并行算法实现44.3.1 主要功能模块与实现方法44.3.2 实验加速比分析54.4 基于Windows API的并行算法实现54.4.1 主要功能模块与实现方法54.4.2 实验加速比分析64.5 基于.net的并行算法实现64.5.1 主要功能模块与实现方法64.5.2 实验加速比分析64.6并行计算技术在实际系统中的应用64.6.1 主要功能模块与实现方法64.6.2 实验加速比分析75. 设计体会76. 附录96.1 基于OpenMP的并行程序设计96.1.1 代码及注释96.1.2 执行结果截图116.1.3 遇到的问题及解决方案126.2 基于MPI的并行程序设计126.1.1 代码及注释126.2.2 执行结果截图126.2.3 遇到的问题及解决方案166.3 基于Java的并行程序设计196.3.1 代码及注释196.3.2 执行结果截图226.3.3 遇到的问题及解决方案236.4 基于Windows API的并行程序设计256.4.1 代码及注释256.4.2 执行结果截图256.4.3 遇到的问题及解决方案306.5 基于.net的并行程序设计306.5.1 代码及注释306.5.2 执行结果截图346.5.3 遇到的问题及解决方案356.6并行计算技术在实际应用系统的应用366.6.1 代码及注释366.6.2 执行结果截图366.6.3 遇到的问题及解决方案421. 设计目的、意义〔功能描述〕设计一个计算向量夹角的WinForm窗体应用,用户只需要在窗体上输入向量的维度,系统随机产生两个向量并将计算结果显示在窗体上。
数值分析实验报告--解线性方程组的迭代法及其并行算法

disp('请注意:高斯-塞德尔迭代的结果没有达 到给定的精度,并且迭代次数已经超过最大迭 代次数max1,方程组的精确解jX和迭代向量X 如下: ') X=X';jX=jX' end end X=X';D,U,L,jX=jX'
高斯-塞德尔的输入为:
A=[10 2 3;2 10 1;3 1 10]; b=[1;1;2]; X0=[0 0 0]'; X=gsdddy(A,b,X0,inf, 0.001,100) A=[10 2 3;2 10 1;3 1 10]; 请注意:因为对角矩阵 D 非奇异,所以此方程组有解.
0.0301 0.0758 0.1834
8.心得体会:
这已经是第三次实验了, 或多或少我已经对 MATLAB 有了更多的了 解与深入的学习。通过这次实验我了解了雅可比迭代法和高斯- 塞德尔迭代法的基本思想,虽然我们不能熟练编出程序,但还是 能看明白的。运行起来也比较容易,让我跟好的了解迭代法的多 样性,使平常手算的题能得到很好的验证。通过这次实验让我对 MATLAB 又有了更深一层的认识,使我对这门课兴趣也更加浓厚。
运行雅可比迭代程序输入: A=[10
b=[1;1;2];X0=[0 0 0]'; X=jacdd(A,b,X0,inf,0.001,100)
2 3;2 10 1;3 1 10];
结果为:
k= 1 X=
0.1000 k= 2 X= 0.0200 k= 3 X= 0.0400 k= 4 X= 0.0276 k= 5 X= 0.0314 k= 6 X= 0.0294 k= 7 X= 0.0301 k= 8 X= 0.0297
6、 设计思想:先化简,把对角线的项提到左边,其它项
华科计算机并行实验报告

课程设计报告题目:并行实验报告课程名称:并行编程原理与实践专业班级:学号:姓名:指导教师:报告日期:计算机科学与技术学院目录1,实验一 (1)1 实验目的与要求 (1)1.1实验目的 (1)1.2实验要求 (1)2 实验内容 (1)2.1.1熟悉pthread编程 (1)2.1.2简单的thread编程 (2)2.2.1熟悉openMP编程 (3)2.3.1熟悉MPI编程 (4)2,实验2~5 (7)1 实验目的与要求 (7)2 算法描述 (7)3.实验方案 (8)4实验结果与分析 (8)3 心得体会 (10)附录: (10)3 蒙特.卡罗算法求π的并行优化 (19)1.蒙特.卡罗算法基本思想 (19)2.工作过程 (20)3.算法描述 (20)4 设计与实现 (21)5 结果比较与分析 (23)6 思考与总结 (24)1,实验一1 实验目的与要求1.1实验目的1)熟悉并行开发环境,能进行简单程序的并行开发,在Linux下熟练操作。
2)熟悉一些并行工具,如pthread,OpenMP,MPI等进行并行编程3)培养并行编程的意识1.2实验要求1)利用pthread、OpenMP、MPI等工具,在Linux下进行简单的并行编程,并且掌握其编译、运行的方法。
2)理解并行计算的基础,理解pthread、OpenMP、MPI等并行方法。
2 实验内容2.1.1熟悉pthread编程Linux系统下的多线程遵循POSIX线程接口,称为 pthread。
编写Linux下的多线程程序,需要使用头文件pthread.h,连接时需要使用库libpthread.a。
下面是pthread编程的几个常用函数:1,int pthread_create(pthread_t *restrict tidp,const pthread_attr_t *restrict attr, void *(*start_rtn)(void),void *restrict arg);返回值:若是成功建立线程返回0,否则返回错误的编号形式参数:pthread_t *restrict tidp 要创建的线程的线程id指针const pthread_attr_t *restrict attr 创建线程时的线程属性void* (start_rtn)(void) 返回值是void类型的指针函数void *restrict arg start_rtn的行参2 , int pthread_join( pthread_t thread, void **retval );thread表示线程ID,与线程中的pid概念类似;retval用于存储等待线程的返回值连接函数pthread_join()是一种在线程间完成同步的方法。
并行计算实验报告一

并行计算实验报告一江苏科技大学计算机科学与工程学院实验报告评定成绩指导教师实验课程:并行计算宋英磊实验名称:Java多线程编程学号: 姓名: 班级: 完成日期:2014年04月22日1.1 实验目的(1) 掌握多线程编程的特点;(2) 了解线程的调度和执行过程;(3) 掌握资源共享访问的实现方法。
1.2 知识要点1.2.1线程的概念(1) 线程是程序中的一个执行流,多线程则指多个执行流;(2) 线程是比进程更小的执行单位,一个进程包括多个线程;(3) Java语言中线程包括3部分:虚拟CPU、该CPU执行的代码及代码所操作的数据。
(4) Java代码可以为不同线程共享,数据也可以为不同线程共享; 1.2.2 线程的创建(1) 方式1:实现Runnable接口Thread类使用一个实现Runnable接口的实例对象作为其构造方法的参数,该对象提供了run方法,启动Thread将执行该run方法;(2) 方式2:继承Thread类重写Thread类的run方法;1.2.3 线程的调度(1) 线程的优先级, 取值范围1,10,在Thread类提供了3个常量,MIN_PRIORITY=1、MAX_ PRIORITY=10、NORM_PRIORITY=5;, 用setPriority()设置线程优先级,用getPriority()获取线程优先级; , 子线程继承父线程的优先级,主线程具有正常优先级。
(2) 线程的调度:采用抢占式调度策略,高优先级的线程优先执行,在Java 中,系统按照优先级的级别设置不同的等待队列。
1.2.4 线程的状态与生命周期说明:新创建的线程处于“新建状态”,必须通过执行start()方法,让其进入到“就绪状态”,处于就绪状态的线程才有机会得到调度执行。
线程在运行时也可能因资源等待或主动睡眠而放弃运行,进入“阻塞状态”,线程执行完毕,或主动执行stop方法将进入“终止状态”。
1.2.5 线程的同步--解决资源访问冲突问题(1) 对象的加锁所有被共享访问的数据及访问代码必须作为临界区,用synchronized加锁。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
两个矩阵相乘的行列划分并行算法摘要:给定两个阶矩阵与,矩阵乘法是指计算C=A×B,现在对两个矩阵乘法进行串行和并行的实验和分析关键词:并行算法;矩阵相乘;算法原理:1、串行算法通常的O(n3)矩阵乘矩阵的串行计算过程如算法1所示,此外为计算矩阵相乘,还可以有对3层循环采用其他嵌套形式的串行算法。
算法1: 稠密矩阵相乘的i,j,k形式串行算法2、并行算法两个矩阵相乘的行列划分并行算法假设一共有P个进程,将矩阵A按行分成P个块,将矩阵B按列分成P个块:每块包含连续若干个行.为使得负载平衡,应使得每块中的行数尽量相等.将A k与B k分别存储在进程P k的A‘与B‘中.将C分为P×P块,且将C i,j存储在P i 的P i′中,如算法2算法2 稠密矩阵乘C=A×B的行列划分并行算法实验由MPICH2在VS2010上进行并行环境的配置来完成,单机情况下用进程数的个数模拟多处理器。
在实验中算法由以下几个函数实现:void readData();此函数被rankID 为0的进程调用,负责从dataIn.txt 文件中A[M,K],B[P,N]两个相乘矩阵的数据,并为结果矩阵C[M,N]分配空间。
其中C[N,N]=A[M,K]*B[P,N]。
int gcd(int M,int N,int group_size) 此函数用来返回两个整数的不大于group_size 的最大公因子,即算法所用到的处理器个数,为了保证行划分和列划分可以平均的划分,通过求M ,N 不大于group_size 的最大公因子来确定实际用到的处理器p 。
void printResult();此函数被rankID 为0的进程调用,用来将A,B,C 矩阵打印输出给用户,并输出用于分发数据和并行计算的时间。
int main(int argc, char **argv) ;程序的主函数。
算法分析(可扩展性分析):在LogP 模型上,算法2并行执行时间为:T p =2n 3p+ps +bn 2由此可知,并行效率为:E p =11+p 2s 2cn 3+bp/(2cn)因此,等效率函数为:W =O(p 3/2)算法的MPI 程序:// matrix.cpp : 定义控制台应用程序的入口点。
//#include "stdafx.h"#include "stdio.h"#include "stdlib.h"#include "mpi.h"#include<mpicxx.h>#define intsize sizeof(int)#define floatsize sizeof(float)#define charsize sizeof(char)#define A(x,y) A[x*K+y]#define B(x,y) B[x*N+y]#define C(x,y) C[x*N+y]#define a(x,y) a[x*K+y]#define b(x,y) b[x*n+y]#define buffer(x,y) buffer[x*n+y] /* 此宏用来简化对标号为奇数的处理器内的缓冲空间的访问*/#define c(l,x,y) c[x*N+y+l*n]float *a,*b,*c,*buffer;int s;float *A,*B,*C; /* A[M,K],B[P,N].正确的情况下K应该等于P,否则无法进行矩阵相乘*/int M,N,K,P ;int m,n;int myid;int p; /* 保存工作站集群中处理器数目,也即通信子大小*/FILE *dataFile; /* 用于读取输入文件内容和将计算结果输出到结果文件的临时文件指针*/MPI_Status status;double time1;double starttime,endtime;/** 函数名: readData* 功能:此函数被rankID为0的进程调用,负责从dataIn.txt文件中读入* A[M,K],B[P,N]两个相乘矩阵的数据,并为结果矩阵C[M,N]分配空间。
* 其中C[N,N]=A[M,K]*B[P,N]* 输入:无* 返回值:无*/void readData(){int i,j;starttime = MPI_Wtime();dataFile=fopen("dataIn.txt","r");fscanf(dataFile,"%d%d", &M, &K); /* 读取矩阵A的行,列数M,K */A=(float *)malloc(floatsize*M*K); /* 为矩阵A分配空间*/ for(i = 0; i < M; i++) /* 读入矩阵A的各元素*/ {for(j = 0; j < K; j++){fscanf(dataFile,"%f", A+i*K+j);}}fscanf(dataFile,"%d%d", &P, &N); /* 读取矩阵B的行,列数P,N */if (K!=P) /* K应该等于P,否则矩阵无法相乘*/{printf("the input is wrong\n");exit(1);}B=(float *)malloc(floatsize*K*N); /* 为矩阵B分配空间*/for(i = 0; i < K; i++) /* 从文件中读入矩阵B的各元素*/{for(j = 0; j < N; j++){fscanf(dataFile,"%f", B+i*N+j);}}fclose(dataFile);printf("Input of file \"dataIn.txt\"\n");printf("%d\t %d\n",M, K); /* 输出A矩阵的维数*/for(i=0;i<M;i++) /* 输出A矩阵的数据*/{for(j=0;j<K;j++) printf("%f\t",A(i,j));printf("\n");}printf("%d\t %d\n",K, N); /* 输出B矩阵的维数*/ for(i=0;i<K;i++) /* 输出B矩阵的数据*/{for(j=0;j<N;j++) printf("%f\t",B(i,j));printf("\n");}C=(float *)malloc(floatsize*M*N); /* 为结果矩阵C[M,N]分配空间*/}/** 函数名: gcd* 功能:此函数用来返回两个整数的不大于group_size的最大公因子* 输入:M,N:要求最大公因数的两个整数* group_size所求公因子必须小于此参数,此参数代表用户指定的通信子大小* 返回值:M和N的不大于group_size的最大公因子*/int gcd(int M,int N,int group_size){int i;for(i=M; i>0; i--){if((M%i==0)&&(N%i==0)&&(i<=group_size))return i;}return 1;}/** 函数名: printResult* 功能:此函数被rankID为0的进程调用,用来将A,B,C矩阵打印输出给用户,* 并输出用于分发数据和并行计算的时间* 输入:无* 返回值:无*/void printResult(){int i,j;printf("\nOutput of Matrix C = AB\n");for(i=0;i<M;i++) /* 输出C矩阵的结果数据*/{for(j=0;j<N;j++) printf("%f\t",C(i,j));printf("\n");}endtime=MPI_Wtime();printf("\n");printf("Whole running time = %f seconds\n",endtime-starttime);printf("Distribute data time = %f seconds\n",time1-starttime);printf("Parallel compute time = %f seconds\n",endtime-time1);}/** 函数名: main* 功能:程序的主函数* 输入:argc为命令行参数个数;* argv为每个命令行参数组成的字符串数组。
* 输出:返回0代表程序正常结束;其它值表明程序出错。
*/int main(int argc, char **argv){int i,j,k,l,group_size,mp1,mm1;MPI_Init(&argc,&argv);MPI_Comm_size(MPI_COMM_WORLD,&group_size);MPI_Comm_rank(MPI_COMM_WORLD,&myid);p=group_size;//下面一段程序负责从dataIn.txt文件中读入A[M,K],B[P,N]两个相乘矩阵的数据,//并为结果矩阵C[M,N]分配空间。
C[N,N]=A[M,K]*B[P,N]//注意这段程序只有编号为0的处理器才执行此步操作if(myid==0){readData();}if (myid==0) /* 由编号为0的进程将A,B两矩阵的行列维数M,K,N发送给所有其他进程*/for(i=1;i<p;i++){MPI_Send(&M,1,MPI_INT,i,i,MPI_COMM_WORLD);MPI_Send(&K,1,MPI_INT,i,i,MPI_COMM_WORLD);MPI_Send(&N,1,MPI_INT,i,i,MPI_COMM_WORLD);}else /* 编号非0的进程负责接收A,B两矩阵的行列维数M,K,N */{MPI_Recv(&M,1,MPI_INT,0,myid,MPI_COMM_WORLD,&status);MPI_Recv(&K,1,MPI_INT,0,myid,MPI_COMM_WORLD,&status);MPI_Recv(&N,1,MPI_INT,0,myid,MPI_COMM_WORLD,&status);}p=gcd(M,N,group_size);m=M/p; /* m代表将矩阵按行分块后每块的行数*/n=N/p; /* m代表将矩阵按列分块后每块的列数*/if(myid<p){a=(float *)malloc(floatsize*m*K); /* a[m,K]用来存储本处理器拥有的矩阵A的行块*/b=(float *)malloc(floatsize*K*n); /* b[K,n]用来存储此时处理器拥有的矩阵B的列块*/c=(float *)malloc(floatsize*m*N); /* c[m,N]用来存储本处理器计算p-1次得到所有结果*/if (myid%2!=0) /* 为标号为奇数的处理器分配发送缓冲空间*/buffer=(float *)malloc(K*n*floatsize);if (a==NULL||b==NULL||c==NULL) /* 如果分配空间出错,则打印出错信息*/printf("Allocate space for a,b or c fail!");if (myid==0) /* 标号为0的处理器将应该它拥有的矩阵A,B的元素读入自己的a,b中*/{for (i=0;i<m;i++)for (j=0;j<K;j++)a(i,j)=A(i,j);for (i=0;i<K;i++)for (j=0;j<n;j++)b(i,j)=B(i,j);}if (myid==0) /* 标号为0的处理器将其他处理器的初始数据分别发给各处理器*/{for (i=1;i<p;i++){MPI_Send(&A(m*i,0),K*m,MPI_FLOAT,i,i,MPI_COMM_WORLD);for (j=0;j<K;j++)MPI_Send(&B(j,n*i),n,MPI_FLOAT,i,i,MPI_COMM_WORLD);}free(A);free(B); /* 至此,A,B两矩阵的数据已经完全被分散到各处理器。