版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/laojiaqi/article/details/33317179
// DFDFDFSSFD.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "stdlib.h"
#include "stdio.h"
#include "mpi.h"
void countRank(int * rank,int perLen,int len,int * p,int * total,int mypid,int size,int flag);
//rank:存放数据的rank值,perLen:rank数组的长度 ,p:保存数据的素组(部分),total:全部数据数组,mypid:进程的ID号,size:进程个数,flag:标志位,//用以区分两种不同的情况
int main(int argc, char *argv[])
{
int *total=0;//0进程
int *p;/*每个进程*/
int *rank;
int *sumRank;
int flag;//整除则为0,否则为1
int mypid,size,len,perLen;//
MPI_Init(&argc,&argv);
MPI_Comm_rank(MPI_COMM_WORLD,&mypid);
MPI_Comm_size(MPI_COMM_WORLD,&size);
if(mypid==0)
{
printf("input number\n");
scanf("%d",&len);
if(len%size==0)//分成两种情况,第一种 任务可以平均分给不同的进程;第二种不能平均分
{
perLen=len/size;
flag=0;
}
else
{
perLen=(len+size-len%size)/size;
flag=1;
}
}
MPI_Bcast(&len,1,MPI_INT,0,MPI_COMM_WORLD);
MPI_Bcast(&flag,1,MPI_INT,0,MPI_COMM_WORLD);//broadcast
MPI_Bcast(&perLen,1,MPI_INT,0,MPI_COMM_WORLD);//broadcast
total=(int*)malloc((perLen*size)*sizeof(int));
if(mypid==0)//输入数据
{
int i=0;
for(i=0;i<len;i++)
scanf("%d",&total[i]);
}
MPI_Bcast(total,len,MPI_INT,0,MPI_COMM_WORLD);//broadcast
p=(int *)malloc(perLen*sizeof(int));
rank=(int *)malloc(perLen*sizeof(int));
sumRank=(int *)malloc((perLen*size)*sizeof(int));
MPI_Scatter(total,perLen,MPI_INT,p,perLen,MPI_INT,0,MPI_COMM_WORLD);//0进程向其他进程分发需要排序的数据
countRank(rank,perLen,len,p,total,mypid,size,flag);//每个进程对发下来的任务,计算每个数的rank值
MPI_Gather(rank,perLen,MPI_INT,sumRank,perLen,MPI_INT,0,MPI_COMM_WORLD);//收集每个进程负责的数据的rank值
if(mypid==0)
{
int i=0;
int *out=(int *)malloc((perLen*size)*sizeof(int));
for(i=0;i<len;i++)//重新排序
{
out[sumRank[i]]=total[i];
}
for(i=0;i<len;i++)//输出
printf("%d ",out[i]);
}
MPI_Finalize();
}
void countRank(int * rank,int perLen,int len,int *p,int * total,int mypid,int size,int flag)//计算rank值
{
int i,j;
if(flag==0||mypid<size-1)//若满足这两个条件之一,就进行计算
{
for(i=0;i<perLen;i++)
{
rank[i]=0;
for(j=0;j<len;j++)
if(p[i]>total[j]||(p[i]==total[j]&&i>j))//第二个条件,是为了满足稳定排序。
rank[i]++;
}
}
else//不能整除的情况,最后一个进程负责的数据
{
for(i=0;i<len%size;i++)
{
rank[i]=0;
for(j=0;j<len;j++)
if(p[i]>total[j]||(p[i]==total[j]&&i>j))
rank[i]++;
}
}
}