枚举排序各种并行之MPI

来源:互联网 发布:java中类的初始化顺序 编辑:程序博客网 时间:2024/05/29 07:43

声明:运行MPI程序之前必须先将mpich配置好,可以参照

http://blog.csdn.net/he_xiang_/article/details/40189257


#include "stdafx.h"#include "mpi.h"          //mpi.h一定好放到stafx.h后面#include <Windows.h>#include <stdio.h>#include <math.h>  #include <stdlib.h>  /* * 函数名: GetRank * 功能: 计算所属部分数据的秩(比该元素小的数的个数) * 输入: HX_data:指向待排序序列的指针 *        HX_DataSize为待排序序列的长度 MyLength为该处理器要排序的序列的长度 rank:指向秩数组的指针 SumID:总处理器个数 MyID:处理器ID * 输出:返回1代表程序正常结束 */  int GetRank(int *data,int DataSize,int MyLength,int *rank,int SumID,int MyID)  {  int i, j;  int start, end;  start=DataSize/SumID*MyID;      /*所属部分数据起始位置*/  end=start+MyLength;             /*所属部分数据结束位置*/  for(j=start;j<end;j++){         /*计算所属部分数据的rank*/  rank[j-start]=0;  for(i=0;i<DataSize;i++){  if((data[j]>data[i]) || ((data[j]==data[i]) && (j>i)))  rank[j-start]++;  }  }  return 1;  }  /* * 函数名: GetDataSize * 功能: 读入待排序序列的长度 * 输入: 待排序序列的长度 * 输出: 返回待排序序列的长度 */  int GetDataSize()  {  int i;  while(1){  fprintf(stderr,"请输入数组的大小:"); fflush(stderr);scanf("%d",&i);  if(i>0) break;  }  return i;  }  /* * 函数名: main * 功能:   主函数,实现枚举排序 * 输入:argc为命令行参数个数; *            argv为每个命令行参数组成的字符串数组 * 输出:返回1代表程序正常结束 */int main(int argc,char *argv[])  {  int DataSize, MyLength;              /*DataSize:数组长度;MyLength:处理器分配到的数据长度*/  int *data_in, *data_out;             /*输入和输出数组指针*/  int *rank;                           /*秩数组*/  int MyID, SumID;  int i, j;double starttime,endtime;MPI_Status status;                     MPI_Init(&argc,&argv);                /*MPI 初始化*/  MPI_Comm_rank(MPI_COMM_WORLD,&MyID);  /*每个处理器确定各自ID*/  MPI_Comm_size(MPI_COMM_WORLD,&SumID); /*每个处理器确定总处理器个数*/fprintf(stderr,"Process %d on %s\n",MyID);fflush(stderr);if(MyID==0)                           /*主处理器*/  DataSize=GetDataSize();       /*读入待排序序列的长度*/  MPI_Bcast(&DataSize, 1, MPI_INT, 0, MPI_COMM_WORLD);  /*主处理器广播待排序序列的长度*/  /*在各个处理器间划分任务*/  MyLength=DataSize/SumID;                if(MyID==SumID-1)                     /*每个处理器确定各自要排序的序列长度*/  MyLength=DataSize-MyLength*(SumID-1);  data_in=(int *)malloc(DataSize*sizeof(int)); /*分配待排序序列的空间*/  if(data_in==0) printf("Malloc memory error!");  if(MyID==0){                       data_out=(int *)malloc(DataSize*sizeof(int)); /*主处理器分配排序后数组的空间*/  if(data_out==0) printf("Malloc memory error!");  rank=(int *)malloc(DataSize*sizeof(int));     /*分配序号数组的空间*/  if(rank==0) printf("Malloc memory error!");  }  else{  rank=(int *)malloc(MyLength*sizeof(int));     /*分配序号数组的空间*/  if(rank==0) printf("Malloc memory error!");  }  if(MyID==0){  int seed;  fprintf(stderr,"请输入随机数的种子:");fflush(stderr);scanf("%d",&seed);                       /*获得随机数的种子*/  srand(seed);           /*srand初始化随机种子*/                 printf("获取随机数\n");  fflush(stderr);for(i=0;i<DataSize;i++){  data_in[i]=((int)rand())%10000;  /*生成随机数,并输出*/  //printf("%10d ",data_in[i]);  }  //printf("\nOutput:");  printf("\n");  }  starttime=MPI_Wtime();/*向各个处理器播送待排序序列*/  MPI_Bcast(data_in, DataSize, MPI_INT, 0, MPI_COMM_WORLD);  /*各个处理器分别计算所属元素的秩*/  GetRank(data_in,DataSize,MyLength,rank,SumID,MyID);  /*从各个处理器收集已排序好的数据*/  if(MyID==0){  for(i=1;i<SumID;i++){  if(i==SumID-1)  MPI_Recv(rank+MyLength*i,DataSize-MyLength*(SumID-1),MPI_INT,i,0,MPI_COMM_WORLD,&status);  else  MPI_Recv(rank+MyLength*i,MyLength,MPI_INT,i,0,MPI_COMM_WORLD,&status);  }  }  else  MPI_Send(rank,MyLength,MPI_INT,0,0,MPI_COMM_WORLD);  /*根据所获得的秩重新定位各个数据*/  if(MyID==0){  for(i=0;i<DataSize;i++)  data_out[rank[i]]=data_in[i];  printf("已排好序的数据\n");for(i=0;i<DataSize;i++){  //printf("%10d ",data_out[i]);  }  printf("\n");  endtime=MPI_Wtime();printf("时间=%f\n",endtime-starttime);}  MPI_Finalize();    return 0;  }  


测试结果正确性:

测试1个进程

测试2个进程

相对加速比:65.7/36..46=1.80

0 0
原创粉丝点击