实施MPI后减速

时间:2015-11-02 15:40:26

标签: c performance mpi

我试图通过编写计算系数来学习MPI。但是,在实施MPI之后,我的程序实际上变慢了。这是我的代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h> 
#include <math.h>
#include <time.h>
#include <mpi.h>

#define aSize 2000000

double stan_dev_mpi(double stan_array[], double stan_mean){

    double a = 0;
    double atemp = 0;

    for (int i=0; i<aSize; i++){
        a = a + pow((stan_array[i]-stan_mean), 2);
    }

    MPI_Allreduce(&a, &atemp, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);

    a = a/aSize;

    a = sqrt(a);

    return a;
}

double mean(double* mean_array){
    double mean = 0;

    for (int i=0; i<aSize; i++){
        mean = mean + mean_array[i];
    }


    mean = mean/aSize;

    return mean;

}

int pearson_par(void){

    int comm_sz; 
    int my_rank;

    double mean_a;
    double mean_b;

    MPI_Init(NULL, NULL);
    MPI_Comm_size(MPI_COMM_WORLD, &comm_sz);
    MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);



    double *a;
    a = malloc(sizeof(double)*aSize);


    double *b;
    b = malloc(sizeof(double)*aSize);

    for (int i=0; i<aSize; i++){
        a[i] = sin(i);
        b[i] = sin(i+2);    

    }

    clock_t begin, end;
    double time_spent;

    begin = clock();





    double *buffera = (double *)malloc(sizeof(double) * (aSize/comm_sz));
    double *bufferb = (double *)malloc(sizeof(double) * (aSize/comm_sz));

    MPI_Scatter(a, aSize/comm_sz, MPI_DOUBLE, buffera, aSize/comm_sz, MPI_DOUBLE, 0, MPI_COMM_WORLD);
    MPI_Scatter(b, aSize/comm_sz, MPI_DOUBLE, bufferb, aSize/comm_sz, MPI_DOUBLE, 0, MPI_COMM_WORLD);



    mean_a = mean(a);
    mean_b = mean(a);

    double stan_dev_a = stan_dev_mpi(a, mean_a);
    double stan_dev_b = stan_dev_mpi(b, mean_b);
    double pearson_numer;
    double pearson_numer_temp;

    for(int i=0; i<aSize; i++){
        pearson_numer = pearson_numer + ((a[i]-mean_a)*(b[i]-mean_b));
    }

    MPI_Allreduce(&pearson_numer, &pearson_numer_temp, 1, MPI_DOUBLE, MPI_SUM,
              MPI_COMM_WORLD);

    pearson_numer = pearson_numer/aSize;

    double pearson_coef = pearson_numer/(stan_dev_a*stan_dev_b);

    if(my_rank == 0){

    printf("%s %G\n", "The Pearson Coefficient is: ", pearson_coef);

    }


    end = clock();

    time_spent = (double)(end - begin) / CLOCKS_PER_SEC;


    if(my_rank == 0){

    printf("%lf %s\n", time_spent, "sec");

    }



    MPI_Finalize();


    free(a);
    free(b);

    return 0;
}

int main(void) {

    pearson_par();

return 0;
} 

如果我使用4个进程运行它,我得到的运行时间为0.06,而使用顺序版运行时为0.03。我是MPI的新手,所以我不确定导致问题的原因。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:2)

我在这里看到的主要问题是您不分发您的工作,而是跨流程复制它。因此,您获得的流程越多,整体工作就越多。实际上,无论MPI流程的数量如何,您的代码的最佳情况都是平坦的时间......

但是,由于你的代码在很多内存访问(非常低的算术强度)下执行的计算非常少,所以很可能是内存限制。因此,增加MPI进程(以及总体工作负载)的数​​量会增加内存带宽的压力(这是跨核心和其后MPI进程的共享资源),您所经历的是时间的增加,而不是平时。 ..

如果您希望在代码中看到任何类型的加速,您必须实际分发工作而不是复制它。这将转化为bufferabufferb数据的计算,而不是ab(实际上a实际上这是另一个错误)。