我试图通过编写计算系数来学习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的新手,所以我不确定导致问题的原因。任何帮助将不胜感激。
答案 0 :(得分:2)
我在这里看到的主要问题是您不分发您的工作,而是跨流程复制它。因此,您获得的流程越多,整体工作就越多。实际上,无论MPI流程的数量如何,您的代码的最佳情况都是平坦的时间......
但是,由于你的代码在很多内存访问(非常低的算术强度)下执行的计算非常少,所以很可能是内存限制。因此,增加MPI进程(以及总体工作负载)的数量会增加内存带宽的压力(这是跨核心和其后MPI进程的共享资源),您所经历的是时间的增加,而不是平时。 ..
如果您希望在代码中看到任何类型的加速,您必须实际分发工作而不是复制它。这将转化为buffera
和bufferb
数据的计算,而不是a
和b
(实际上a
实际上这是另一个错误)。