lastTest
学号:2019301110060 姓名:刘振平 院系:植物科学技术学院
1.二维数组乘积
#include "mpi.h"
#include "omp.h"
#include <malloc.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int rank, numprocess, dimension;
double startTime, endTime;
float *Matrix1;
float *Matrix2;
float *sendBuf, *revBuf;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &numprocess);
MPI_Barrier(MPI_COMM_WORLD);
startTime = MPI_Wtime();
if (rank == 0)
{
printf("请输入矩阵的维度·:\n");
scanf("%d", &dimension);
Matrix1 = (float *)malloc(dimension * dimension * sizeof(float));
Matrix2 = (float *)malloc(dimension * dimension * sizeof(float));
for (int i = 0; i < dimension; i++)
{
// srand(rank*i+1);
for (int j = 0; j < dimension; j++)
{
Matrix1[i * dimension + j] = 100.0 * rand() / RAND_MAX;
Matrix2[i * dimension + j] = 100.0 * rand() / RAND_MAX;
}
}
revBuf = (float *)malloc(dimension * dimension * sizeof(float));
}
/*
广播二维数组
*/
MPI_Bcast(&dimension, 1, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Bcast(&Matrix1, dimension * dimension, MPI_FLOAT, 0, MPI_COMM_WORLD);
MPI_Bcast(&Matrix2, dimension * dimension, MPI_FLOAT, 0, MPI_COMM_WORLD);
sendBuf = (float *)malloc(dimension * sizeof(float));
for (int i = rank; i < dimension; i += numprocess)
{
for (int j = 0; j < dimension; j++)
{
for (int k = 0; k < dimension; k++)
{
sendBuf[j] = Matrix1[i * dimension + k] * Matrix2[k * dimension + j];
}
}
MPI_Gather(sendBuf, dimension, MPI_FLOAT, revBuf, dimension, MPI_FLOAT, 0, MPI_COMM_WORLD);
}
MPI_Barrier(MPI_COMM_WORLD);
endTime = MPI_Wtime();
if (rank == 0)
{
for (int i = 0; i < dimension; i++)
{
// srand(rank*i+1);
for (int j = 0; j < dimension; j++)
{
printf("%f\t",revBuf[i*dimension+j]);
}
printf("\n");
}
printf("time= %g(s)\n", endTime - startTime);
}
free(Matrix1);
free(Matrix2);
MPI_Finalize();
return 0;
}2.计算数列加和值
2.1MPI模式
根据进程数将N拆分成多个部分
2.2MPi+OpenMp模式
根据进程ID拆分每个进程的计算范围
在每个范围中使用多线程进行计算
2.3并行效率和加速比
取N=10000000000
线程数
时间
加速比
并行效率
1
5.42
1
1
2
5.36
1.01
0.505
4
5.54
0.97
0.2425
6
5.38
1.0
0.16
8
5.46
0.99
0.123
3.所有计算的PI
3.1OMP多线程计算PI
3.1.1PAD模式
PAD模式进行多线程计算PI,利用二维数组存储计算结果
在多线程结束后,遍历数组获取对应的pi值
防止了多线程在输入输出时,造成的阻塞
3.1.2并行域模式
使用一维数组存储计算结果,所以会造成数据读写时的阻塞
3.1.3reduction 制导
在并行域中,使用reduction制导语句将最终结果直接累加到sum变量
省去了for循环的遍历,以及多个线程对数据的读写
3.2MPI多进程模式
使用MPI_Scatter将要计算的范围分发给各个进行
使用MPI_Gather将每个进程的结果汇总到0号进程
3.3MPI和OpenMPI混合模式
根据进程ID计算每个进程所要计算的范围
每个进行使用多线程进行计算,使用reduction制导语句将多个线程的结果汇总
使用MPI_Reduce将多个进程的计算结果进行汇总
Last updated
Was this helpful?