⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 psrs_sort.c

📁 并行程序设计示例之一
💻 C
字号:
#include <stdio.h>#include <stdlib.h>#include <mpi.h>#define INIT_TYPE 10#define ALLTOONE_TYPE 100#define ONETOALL_TYPE 200#define MULTI_TYPE 300#define RESULT_TYPE 400#define RESULT_LEN 500#define MULTI_LEN 600int Spt;long DataSize;int *arr,*arr1;int mylength;int *index;int *temp1;main(int argc,char* argv[]){    long BaseNum = 1;    int PlusNum;    int MyID;    MPI_Init(&argc,&argv);    MPI_Comm_rank(MPI_COMM_WORLD,&MyID);    PlusNum=60;    DataSize = BaseNum*PlusNum;    if (MyID==0)        printf("The DataSize is : %lu\n",PlusNum);    Psrs_Main();    if (MyID==0)        printf("\n");    MPI_Finalize();}Psrs_Main( ){    int i,j;    int MyID,SumID;    int n,c1,c2,c3,c4,k,l;    FILE * fp;    int ready;    MPI_Status status[32*32*2];    MPI_Request request[32*32*2];    MPI_Comm_rank(MPI_COMM_WORLD,&MyID);    MPI_Comm_size(MPI_COMM_WORLD,&SumID);    Spt = SumID-1;	/*初始化参数*/    arr = (int *)malloc(2*DataSize*sizeof(int));    if (arr==0) merror("malloc memory for arr error!");    arr1 = &arr[DataSize];    if (SumID>1)    {        temp1 = (int *)malloc(sizeof(int)*SumID*Spt);        if (temp1==0) merror("malloc memory for temp1 error!");        index = (int *)malloc(sizeof(int)*2*SumID);        if (index==0) merror("malloc memory for index error!");    }    MPI_Barrier( MPI_COMM_WORLD);    mylength = DataSize / SumID;    srand(MyID);    printf("This is node %d \n",MyID);    printf("On node %d the input data is:\n",MyID);    for (i=0;i<mylength;i++)    {        arr[i] = (int)rand();        printf("%d : ",arr[i]);    }    printf("\n");	/*每个处理器将自己的n/P个数据用串行快速排序(Quicksort),得到一个排好序的序列,对应于算法13.5步骤(1)*/    MPI_Barrier( MPI_COMM_WORLD);    quicksort(arr,0,mylength - 1);    MPI_Barrier( MPI_COMM_WORLD);	/*每个处理器从排好序的序列中选取第w,2w,3w,…,(P-1)w个共P-1个数据作为代表元素,其中w=n/P*P,对应于算法13.5步骤(2)*/    if (SumID>1)    {        MPI_Barrier(MPI_COMM_WORLD);        n = (int)(mylength/(Spt+1));        for (i=0;i<Spt;i++)            temp1[i] = arr[(i+1)*n-1];        MPI_Barrier(MPI_COMM_WORLD);        if (MyID==0)        {			/*每个处理器将选好的代表元素送到处理器P0中,对应于算法13.5步骤(3) */            j = 0;            for (i=1;i<SumID;i++)                MPI_Irecv(&temp1[i*Spt], sizeof(int)*Spt, MPI_CHAR, i,ALLTOONE_TYPE+i, MPI_COMM_WORLD, &request[j++]);            MPI_Waitall(SumID-1, request, status);			/* 处理器P0将上一步送来的P段有序的数据序列做P路归并,再选择排序后的第P-1,2(P-1),…,(P-1)(P-1)个共P-1个主元,,对应于算法13.5步骤(3)*/            MPI_Barrier(MPI_COMM_WORLD);            quicksort(temp1,0,SumID*Spt-1);            MPI_Barrier( MPI_COMM_WORLD);            for (i=1;i<Spt+1;i++)                temp1[i] = temp1[i*Spt-1];			/*处理器P0将这P-1个主元播送到所有处理器中,对应于算法13.5步骤(4)*/            MPI_Bcast(temp1, sizeof(int)*(1+Spt), MPI_CHAR, 0, MPI_COMM_WORLD);            MPI_Barrier(MPI_COMM_WORLD);        }        else        {            MPI_Send(temp1,sizeof(int)*Spt,MPI_CHAR,0,ALLTOONE_TYPE+MyID, MPI_COMM_WORLD);            MPI_Barrier( MPI_COMM_WORLD);            MPI_Barrier( MPI_COMM_WORLD);            MPI_Bcast(temp1, sizeof(int)*(1+Spt), MPI_CHAR, 0, MPI_COMM_WORLD);            MPI_Barrier(MPI_COMM_WORLD);        }		/*每个处理器根据上步送来的P-1个主元把自己的n/P个数据分成P段,记为处理器Pi的第j+1段,其中i=0,…,P-1,j=0,…,P-1,对应于算法13.5步骤(5)*/        n = mylength;        index[0] = 0;        i = 1;        while ((arr[0]>=temp1[i])&&(i<SumID))        {            index[2*i-1] = 0;            index[2*i] = 0;            i++;        }        if (i==SumID) index[2*i-1] = n;        c1 = 0;        while (i<SumID)        {            c4 = temp1[i];            c3 = n;            c2 = (int)((c1+c3)/2);            while ((arr[c2]!=c4)&&(c1<c3))            {                if (arr[c2]>c4)                {                    c3 = c2-1;                    c2 = (int)((c1+c3)/2);                }                else                {                    c1 = c2+1;                    c2 = (int)((c1+c3)/2);                }            }            while ((arr[c2]<=c4)&&(c2<n)) c2++;            if (c2==n)            {                index[2*i-1] = n;                for (k=i;k<SumID;k++)                {                    index[2*k] = 0;                    index[2*k+1] = 0;                }                i = SumID;            }            else            {                index[2*i] = c2;                index[2*i-1] = c2;            }            c1 = c2;            c2 = (int)((c1+c3)/2);            i++;        }        if (i==SumID) index[2*i-1] = n;        MPI_Barrier( MPI_COMM_WORLD);		/*每个处理器送它的第i+1段给处理器Pi,从而使得第i个处理器含有所有处理器的第i段数据(i=0,…,P-1),,对应于算法13.5步骤(6)*/        j = 0;        for (i=0;i<SumID;i++)        {            if (i==MyID)            {                temp1[i] = index[2*i+1]-index[2*i];                for (n=0;n<SumID;n++)                    if (n!=MyID)                {                    k = index[2*n+1]-index[2*n];                    MPI_Send(&k, sizeof(int), MPI_CHAR, n, MULTI_LEN+MyID,MPI_COMM_WORLD);                }            }            else            {                MPI_Recv(&temp1[i], sizeof(int), MPI_CHAR, i,MULTI_LEN+i, MPI_COMM_WORLD, &status[j++]);            }        }        MPI_Barrier(MPI_COMM_WORLD);        j = 0;        k = 0;        l = 0;        for (i=0;i<SumID;i++)        {            MPI_Barrier(MPI_COMM_WORLD);            if (i==MyID)            {                for (n=index[2*i];n<index[2*i+1];n++)                    arr1[k++] = arr[n];            }            MPI_Barrier(MPI_COMM_WORLD);            if (i==MyID)            {                for (n=0;n<SumID;n++)                    if (n!=MyID)                {                    MPI_Send(&arr[index[2*n]], sizeof(int)*(index[2*n+1]-index[2*n]),MPI_CHAR, n, MULTI_TYPE+MyID, MPI_COMM_WORLD);                }            }            else            {                l = temp1[i];                MPI_Recv(&arr1[k], l*sizeof(int), MPI_CHAR, i ,MULTI_TYPE+i, MPI_COMM_WORLD, &status[j++]);                k=k+l;            }            MPI_Barrier(MPI_COMM_WORLD);        }        mylength = k;        MPI_Barrier(MPI_COMM_WORLD);		/*每个处理器再通过P路归并排序将上一步的到的数据排序;从而这n个数据便是有序的,,对应于算法13.5步骤(7) */        k = 0;        multimerge(arr1,temp1,arr,&k,SumID);        MPI_Barrier(MPI_COMM_WORLD);    }    printf("On node %d the sorted data is : \n",MyID);    for (i=0;i<mylength;i++)        printf("%d : ",arr[i]);    printf("\n");}/*输出错误信息*/merror(char* ch){    printf("%s\n",ch);    exit(1);}/*串行快速排序算法*/quicksort(int *datas,int bb,int ee){    int tt,i,j;    tt = datas[bb];    i = bb;    j = ee;    if (i<j)    {        while(i<j)        {            while ((i<j)&&(tt<=datas[j])) j--;            if (i<j)            {                datas[i] = datas[j];                i++;                while ((i<j)&&(tt>datas[i])) i++;                if (i<j)                {                    datas[j] = datas[i];                    j--;                    if (i==j) datas[i] = tt;                }                else datas[j] = tt;            } else datas[i] = tt;        }        quicksort(datas,bb,i-1);        quicksort(datas,i+1,ee);    }}/*串行多路归并算法*/multimerge(int *data1,int *ind,int *data,int *iter,int SumID){    int i,j,n;    j = 0;    for (i=0;i<SumID;i++)        if (ind[i]>0)    {        ind[j++] = ind[i];        if (j<i+1) ind[i] = 0;    }    if ( j>1 )    {        n = 0;        for (i=0;i<j,i+1<j;i=i+2)        {            merge(&(data1[n]),ind[i],ind[i+1],&(data[n]));            ind[i] += ind[i+1];            ind[i+1] = 0;            n += ind[i];        }        if (j%2==1 )            for (i=0;i<ind[j-1];i++) data[n++]=data1[n];        (*iter)++;        multimerge(data,ind,data1,iter,SumID);    }}merge(int *data1,int s1,int s2,int *data2){    int i,l,m;    l = 0;    m = s1;    for (i=0;i<s1+s2;i++)    {        if (l==s1)            data2[i]=data1[m++];        else        if (m==s2+s1)            data2[i]=data1[l++];        else        if (data1[l]>data1[m])            data2[i]=data1[m++];        else            data2[i]=data1[l++];    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -