Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 在实现MPI后放慢速度_C_Performance_Mpi - Fatal编程技术网

C 在实现MPI后放慢速度

C 在实现MPI后放慢速度,c,performance,mpi,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(dou

我试图通过编写一个计算系数的程序来学习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;
} 
#包括
#包括
#包括
#包括
#包括
#包括
#定义aSize 2000000
双标准偏差mpi(双标准阵列[],双标准均值){
双a=0;
双atemp=0;

对于(int i=0;i而言,我在这里看到的主要问题是,您不分配您的工作,而是跨进程复制它。因此,您得到的进程越多,总体上所做的工作就越多。实际上,对于您的代码来说,最好的情况是,无论MPI进程的数量如何,都有一个固定的时间

但是,由于您的代码对大量内存访问(非常低的算术强度)的计算量非常少,因此您可能会受到内存限制。因此,增加MPI进程的数量(以及总体工作负载)会增加内存带宽的压力(这是一种跨内核和MPI进程的共享资源),你所经历的不是平淡的时间,而是时间的增加


如果你想有机会在你的代码中看到任何形式的加速,你必须实际分配工作,而不是复制它。这将转化为在你的
buffera
bufferb
数据上进行计算,而不是
a
b
(实际上
a
这是另一个bug).

即使增加计数,速度下降是否仍然存在?相对于工作量,可能会有很多开销。是的,不管怎样,我的速度都非常相似