asc18超算mpi学习总结1

1. MPI_Init(&argc, &argv);初始化,MPI_Finalize();结束

所有mpi函数在Init之后执行,但每个进程都会拥有整个代码,不只是两者之间的代码,每个进程都会有变量的私有备份。

2. MPI_Comm_size(MPI_COMM_WORLD, &nproces);总进程数

   MPI_Comm_rank(MPI_COMM_WORLD, &rank);当前进程

3. MPI_Wtime();获取时间,浮点数

4. MPI_Get_processor_name(name, &len); 获取当前主机,len为长度

5. MPI_Get_version(&a, &b);获取mpi主版本次版本号

6. MPI_Send(buf, 2, MPI_INT, i, 1, MPI_COMM_WORLD);

MPI_Recv(buf, 2, MPI_INT, i, 1, MPI_COMM_WORLD, &status);

Send 发送之后,如果对相同进程发送数据,形成缓冲区,不会覆盖前面一个,Recv会一个一个的接收。

7. MPI_STATUS 有 MPI_TAG MPI_SOURCE MPI_ERROR

8. MPI_Barrier(MPI_COMM_WORLD);等待进程同步

9. MPI_ANY_SOURCE //任意源  MPI_ANY_TAG //任意tag

10. Jacobi迭代(对等模式mpi并行化)

asc18超算mpi学习总结1_第1张图片

左右两边都保留一列,

遇到的问题:边界处理,所有第0行最后一行赋值为8,左边第1列为8,右边第my_size8,左边第0列留空,右边第my_size+1留空,这地方在最后计算时注意边界处理。0进程从2开始到my_size3进程从1开始到my_size-1

1.  MPI_Sendrecv(t, totalsize, MPI_DOUBLE, rank+1, 1, t, totalsize, MPI_DOUBLE, rank+1, 0, MPI_COMM_WORLD, &status); sendrecv整合,这个函数比分开写号,系统会优化进程通信避免死锁。

2.   MPI_Sendrecv_replace(t, totalsize, MPI_DOUBLE, rank+1, 1, rank+1,0,MPI_COMM_WORLD, &status); 因为发送和接收都一样大小并且类型一样,共用缓冲区。

3.  MPI_PROC_NULL  值为-1,虚拟进程,向这个进程发送接收数据时,会返回真,执行一个空操作,简化代码,减少边界操作。

4. 矩阵向量乘(主从模式并行)

asc18超算mpi学习总结1_第2张图片

a[4][4]  b[4]

行分解:将a按行分为几块,比如当前进程数为3,将a分为2块,给进程1,20号进程负责广播和输出。

1负责1.2行,2负责34行或者  1负责 1 3行,2负责24行。

两种不同的分配方法,一种是顺序分配一种是取余分配。

a的第一行乘以bc的第一个值。每一行都要乘以b,所以对于每个进程来说,b是共享的。用MPI_Bcastb广播给所有进程。计算结果要返回给0进程。每一行计算完都返回给0进程,将每一个MPI_Send tag设置为当前行数,0进程接收到时根据status取出tag,便于对c的赋值。

1. 列分解(未实现)

asc18超算mpi学习总结1_第3张图片

a的每一列乘以bb依然是共享的,a[0][0] * b[0] 得到 c[0] 的一部分,a[0][1]*b[0]c[0]的第二部分,第一个进程得到每个c的两部分,每个进程发送时发送一个temp数组即可包含了c的部分值,将每个进程的c加和得到最终的C

1. 矩阵乘

行分解类似矩阵向量乘,b依然是共享的,每个进程发送时,发送的是矩阵c的一行,并且tag依然代表了计算的行。

列分解(未实现)得到的是矩阵c所有值的一部分,每个进程对c的每个值加和可得c,似乎好实现。

块分解(未实现)将a行分解,b列分解,进程中的ab相乘的c[i][j]。。。等等,计算完之后将b发给其他进程,迭代,这样每个进程都可以得到完整的b

asc18超算mpi学习总结1_第4张图片


你可能感兴趣的:(asc竞赛)