/*
文件名:
mpi_structs.c
目的:
该代码用于测试向量类型、结构类型、打包解包的传输效率
测试传输的数据是100000个MPI_DOUBLE类型,且以24为间隔存储的数据
派生数据类型相关的函数:
MPI_Type_vector
MPI_Type_create_struct(新)/MPI_Type_struct(弃)
MPI_Type_commit
MPI_Type_extent
运行:
mpicc -g mpi_structs.c -o mpi_structs -Wall
mpirun -n 2 ./mpi_structs
*/
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include "mpi.h"
#define NUMBER_OF_TESTS 10 // 重复运行的次数
int main(int argc, char *argv[]){
MPI_Datatype vec1, vec_n;
int blocklens[2];
MPI_Aint indices[2];
MPI_Datatype old_types[2];
double *buf, // 原数据所在的不连续的缓冲区
*lbuf; // 打包所需的连续存储的缓冲区
register double *in_p, *out_p;
int rank;
int n, stride;
double t1, t2, tmin;
int i, j, k, nloop;
MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
n = 1000; // vec1中块的个数
stride = 24; // vec1中每个块起始位置的间隔
nloop = 100000 / n; // 一共100,000个MPI_DOUBLE类型的数据,分成nloop个vec1类型进行传输
buf = (double *)malloc(n*stride*sizeof(double));
if(!buf){
fprintf(stderr, "Could not allocate send/recv buffer of size %d\n", n*stride);
MPI_Abort(MPI_COMM_WORLD, 1);
}
lbuf = (double *)malloc(n*sizeof(double));
if(!buf){
fprintf(stderr, "Could not allocate send/recv lbuffer of size %d\n", n);
MPI_Abort(MPI_COMM_WORLD, 1);
}
if(rank == 0)
printf("Kind\t\t n\t stride\t time(sec)\t Rate(MB/sec)\n");
/* 向量类型的传输 */
MPI_Type_vector(n, 1, stride, MPI_DOUBLE, &vec1);
MPI_Type_commit(&vec1);
/* 打印派生数据类型的跨度 */
if(rank == 0){
MPI_Aint ext[1];
MPI_Type_extent(MPI_DOUBLE, ext);
printf("extent of MPI_DOUBLE : %d\n",(int)(*ext));
// extent of MPI_DOUBLE: 8
MPI_Type_extent(vec1, ext);
printf("extent of vec1 : %d\n",(int)(*ext));
// extent of vec1: 191816 = (n-1)*stride*ex(MPI_DOUBLE)+ex(MPI_DOUBLE)
}
tmin = 1000;
// 重复计算10遍时间,取其中运行的最短时间为tmin
for
MPI笔记:派生数据类型相关例子
最新推荐文章于 2023-09-02 22:21:28 发布