Mo_Cuishle_ 2017-04-05 12:25 采纳率: 20%
浏览 1169
已结题

mpi并行计算矩阵转置时间远慢于串行 为什么

如题,进行并行计算课程实验时利用mpi编程在学校服务器上进行程序运行计算10000*10000矩阵转置计算

代码如下

 #include "stdio.h"
#include "stdlib.h"
#include "mpi.h"
#include "math.h"

#define E 0.0001
#define a(x,y) a[x*m+y]
#define b(x,y) b[x*m+y]
#define A(x,y) A[x*size+y]
#define B(x,y) B[x*size+y]
#define intsize sizeof(int)
#define floatsize sizeof(float)
#define charsize sizeof(char)

int size,N;                                       /* size:±£´æ¾ØÕóÐÐÊý;N:±£´æ¾ØÕóÁÐÊý */
int m;                                            /* ±£´æ×Ó·½ÕóµÄ³ß´ç */
int t;                                            /* ÆåÅÌ»®·ÖµÄ·Ö¸îÊý */
float *A, *B;                                     /* A:±£´æÔ­¾ØÕó;B:±£´æתÖúóµÄ¾ØÕó */
double starttime;                                 /* ±£´æ¿ªÊ¼Ê±¼ä */
double time1;                                     /* ±£´æ·Ö·¢Êý¾ÝµÄ½áÊøʱ¼ä */
double time2;                                     /* ±£´æÔËÐеĽáÊøʱ¼ä */
int my_rank;                                      /* ±£´æµ±Ç°½ø³ÌµÄ½ø³ÌºÅ */
int p;                                            /* ±£´æ½ø³ÌÊý */
MPI_Status status;                                /* ±£´æMPI״̬ */
FILE *fdA;                                        /* ÊäÈëÎļþ */

/* ÔËÐнáÊøÇ°,µ÷Óñ¾º¯ÊýÊÍ·ÅÄÚ´æ¿Õ¼ä */
void Environment_Finalize(float *a,float *b)
{
    free(a);
    free(b);
}

int main(int argc, char **argv)
{
    int i,j,k,my_rank,group_size;
    float *a,*b;
    int u,v;
    float temp;

    MPI_Init(&argc,&argv);
    MPI_Comm_size(MPI_COMM_WORLD,&group_size);
    MPI_Comm_rank(MPI_COMM_WORLD,&my_rank);
    p=group_size;

    /* Èç¹ûÊÇÖ÷½ø³Ì(rank=0µÄ½ø³Ì),Ôò½øÐжÁÎļþµÄ²Ù×÷,
       ½«´ýתÖõľØÕó¶ÁÈëÄÚ´æ,±£´æµ½È«¾Ö±äÁ¿AÖÐ
    */
    if(my_rank==0)
    {
        starttime=MPI_Wtime();
        fdA=fopen("mat_data.txt","r");
        /* ¶ÁÈë¾ØÕóµÄÐÐÊýºÍÁÐÊý,²¢±£´æµ½sizeºÍNÖÐ */
        fscanf(fdA,"%d %d", &size, &N);
        /* ÅжÏÊÇ·ñÊÇ·½Õó,Èç¹û²»ÊÇ,³ÌÐòÍ˳ö */
        if(size != N)
        {
            puts("The input is error!");
            exit(0);
        }
        A=(float*)malloc(floatsize*size*size);
        B=(float*)malloc(floatsize*size*size);
        /* ½«¾ØÕóµÄËùÓÐÖµ¶ÁÈë,±£´æµ½AÖÐ */
        for(i = 0; i < size; i ++)
        {
            for(j = 0; j < size; j ++) fscanf(fdA, "%f", A+i*size+j);
        }
        fclose(fdA);
    }
    /* ¹ã²¥¾ØÕóµÄ³ß´ç */
    MPI_Bcast(&size,1,MPI_INT,0,MPI_COMM_WORLD);

    /* »ñµÃÆåÅÌ»®·ÖµÄÊýÄ¿ */
    t=(int)sqrt(p);
    if (t>size)
        t=size;
    if(size%t!=0)
        for(;;)
    {
        t--;
        if(size%t==0)
            break;
    }
    /* »ñµÃʵ¼ÊÀûÓõĴ¦ÀíÆ÷¸öÊý */
    p=t*t;
    /* ÿ¸ö×Ó·½ÕóµÄ³ß´ç */
    m=size/t;

    /* a±£´æ×Ó·½Õó,bÊÇÁÙʱ¾ØÕó,ÊÇÖ÷½ø³ÌÓÃÀ´±£´æ´ý·¢Ë͸ø±ðµÄ½ø³ÌµÄ×Ó·½Õó */
    a=(float *)malloc(floatsize*m*m);
    b=(float *)malloc(floatsize*m*m);

    if (a==NULL||b==NULL)
        printf("allocate space  fail!");

    /* ¶ÔÖ÷½ø³Ì,»ñµÃ×Ô¼ºµÄ×Ó·½Õó(¼´×óÉϽǵÄ×Ó·½Õó) */
    if (my_rank==0)
    {
        for(i=0;i<m;i++)
            for(j=0;j<m;j++)
                a(i,j)=A(i,j);
    }

    /* Ö÷½ø³ÌÏòÆäËû½ø³Ì·¢ËÍÊý¾Ý */
    if (my_rank==0)
    {
        for(i=1;i<p;i++)
        {
            v=i/t;                                /* ×Ó·½ÕóµÄÐкŠ*/
            u=i%t;                                /* ×Ó·½ÕóµÄÁкŠ*/

            for(j=v*m;j<(v+1)*m;j++)
                for(k=u*m;k<(u+1)*m;k++)
                    b((j%m),(k%m))=A(j,k);        /* ½«×Ó·½ÕóÔÝ´æÔÚbÖÐ */

                                                  /* ½«×Ó·½Õó·¢Ë͵½ÏàÓ¦µÄ½ø³Ì */
            MPI_Send(b,m*m,MPI_FLOAT,i,i,MPI_COMM_WORLD);
        }
    }
    else if (my_rank<p)                           /* ¶ÔÆäËû½ø³Ì,´ÓÖ÷½ø³Ì½ÓÊÕÊý¾Ý */
        MPI_Recv(a,m*m,MPI_FLOAT,0,my_rank,MPI_COMM_WORLD,&status);

    time1=MPI_Wtime();

    /* ¶ÔÏÂÈý½ÇµÄ×Ó·½Õó½øÐд¦Àí */
    if ((my_rank/t)>(my_rank%t)&&my_rank<p)
    {
        v=my_rank/t;                              /* ÐкŠ*/
        u=my_rank%t;                              /* ÁкŠ*/

        /* ·¢ËÍ×Ó·½Õóµ½Î»ÓÚÏàÓ¦ÉÏÈý½ÇλÖõĽø³Ì */
        MPI_Send(a,m*m,MPI_FLOAT,(u*t+v),(u*t+v),MPI_COMM_WORLD);
        /* ´ÓÏàÓ¦ÉÏÈý½ÇλÖõĽø³Ì½ÓÊÕÊý¾Ý */
        MPI_Recv(a,m*m,MPI_FLOAT,(u*t+v),my_rank,MPI_COMM_WORLD,&status);
    }

    /* ¶ÔÉÏÈý½ÇµÄ×Ó·½Õó½øÐд¦Àí */
    if ((my_rank/t)<(my_rank%t)&&my_rank<p)
    {
        v=my_rank/t;                              /* ÐкŠ*/
        u=my_rank%t;                              /* ÁкŠ*/
        /* ½«×Ó·½ÕóÔªËظ´ÖƵ½b */
        for(i=0;i<m;i++)
            for(j=0;j<m;j++)
                b(i,j)=a(i,j);

        /* ´ÓÏàÓ¦ÏÂÈý½ÇλÖõĽø³Ì½ÓÊÕÊý¾Ý */
        MPI_Recv(a,m*m,MPI_FLOAT,(u*t+v),my_rank,MPI_COMM_WORLD,&status);
        /* ×Ó·½Õó·¢Ë͵½Î»ÓÚÏàÓ¦ÏÂÈý½ÇλÖõĽø³Ì */
        MPI_Send(b,m*m,MPI_FLOAT,(u*t+v),(u*t+v),MPI_COMM_WORLD);
    }

    /* ¶Ôÿһ¸ö×Ó·½Õó½øÐÐתÖà */
    for(i=1;i<m;i++)
        for(j=0;j<i;j++)
    {
        temp=a(i,j);
        a(i,j)=a(j,i);
        a(j,i)=temp;
    }

    /* Ö÷½ø³Ì¿ªÊ¼½«×ªÖõĽá¹û½øÐÐ×éºÏ
       ÏȽ«Ö÷½ø³ÌµÄ½á¹û×éºÏµ½BÖÐ×óÉϽÇ
    */
    if (my_rank==0)
    {
        for(i=0;i<m;i++)
            for(j=0;j<m;j++)
                B(i,j)=a(i,j);
    }
    /* Ö÷½ø³Ì´ÓÆäËû½ø³Ì½ÓÊÕ½á¹û,×éºÏµ½BµÄÏàӦλÖà */
    if (my_rank==0)
    {
        for(i=1;i<p;i++)
        {
            /* ´ÓÆäËû½ø³Ì½ÓÊÕ½á¹û */
            MPI_Recv(a,m*m,MPI_FLOAT,i,i,MPI_COMM_WORLD,&status);

            v=i/t;                                /* ½á¹ûµÄÐкŠ*/
            u=i%t;                                /* ½á¹ûµÄÁкŠ*/

            for(j=v*m;j<(v+1)*m;j++)
                for(k=u*m;k<(u+1)*m;k++)
                    B(j,k)=a((j%m),(k%m));        /* ½á¹û×éºÏµ½BµÄÏàӦλÖà */
        }
    }
    else if(my_rank<p)                            /* ÆäËû½ø³Ì·¢Ëͽá¹ûµ½Ö÷½ø³Ì */
        MPI_Send(a,m*m,MPI_FLOAT,0,my_rank,MPI_COMM_WORLD);

    /* ÓÉÖ÷½ø³Ì´òÓ¡¼ÆËã½á¹û */
    // if (my_rank==0)
    // {
    //     printf("Input of file \"dataIn.txt\"\n");
    //     printf("%d\t%d\n", size, size);
    //     for(i=0;i<size;i++)
    //     {
    //         for(j=0;j<size;j++) printf("%f\t",A(i,j));
    //         printf("\n");
    //     }
    //     printf("\nOutput of Matrix AT\n");
    //     for(i=0;i<size;i++)
    //     {
    //         for(j=0;j<size;j++) printf("%f\t",B(i,j));
    //         printf("\n");
    //     }
    // }
    time2=MPI_Wtime();
    /* ÓÉÖ÷½ø³Ì´òӡʱ¼äÐÅÏ¢ */
    if (my_rank==0)
    {
        printf("\n");
        printf("Whole running time    = %f seconds\n",time2-starttime);
        printf("Distribute data time  = %f seconds\n",time1-starttime);
        printf("Parallel compute time = %f seconds\n",time2-time1);
    }
    MPI_Barrier(MPI_COMM_WORLD);
    MPI_Finalize();
    Environment_Finalize(a,b);
    return(0);
}

增加进程数时间总体是增大的
如图图片说明
请问为什么

  • 写回答

0条回答 默认 最新

    报告相同问题?

    悬赏问题

    • ¥50 如何增强飞上天的树莓派的热点信号强度,以使得笔记本可以在地面实现远程桌面连接
    • ¥15 MCNP里如何定义多个源?
    • ¥20 双层网络上信息-疾病传播
    • ¥50 paddlepaddle pinn
    • ¥20 idea运行测试代码报错问题
    • ¥15 网络监控:网络故障告警通知
    • ¥15 django项目运行报编码错误
    • ¥15 请问这个是什么意思?
    • ¥15 STM32驱动继电器
    • ¥15 Windows server update services