C 在实现MPI后放慢速度
我试图通过编写一个计算系数的程序来学习MPI。然而,在实现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
#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).即使增加计数,速度下降是否仍然存在?相对于工作量,可能会有很多开销。是的,不管怎样,我的速度都非常相似