2015-11-02 50 views
1

我正試圖通過編寫程序來計算係數來學習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.03 0.06的運行時間。我是MPI的新手,所以我不確定是什麼導致了問題。任何幫助,將不勝感激。

+0

即使增加計數,速度是否會下降?相對於工作量來說,可能會有很多開銷。 –

+0

是的,無論如何,我的速度都非常接近 – user2320239

回答

3

我在這裏看到的主要問題是,您不會分發您的工作,而是跨進程複製它。所以你得到的流程越多,你做的整體工作就越多。實際上,對於你的代碼來說,最好的情況是不考慮MPI進程的數量而保持一個平坦的時間...

但是因爲此外你的代碼對很多內存訪問做的計算很少(非常低的算術強度),你可能會受到內存限制。因此,增加MPI進程(以及整體工作負載)的數​​量會增加內存帶寬的壓力(這是跨內核和之後的MPI進程的共享資源),您所體驗的是,而不是平坦的時間,增加時間。 ..

如果您希望在代碼中看到任何加速的機會,您必須實際分發工作而不是複製它。這將轉化爲對您的bufferabufferb數據的計算,而不是ab(以及a實際上在這裏是另一個錯誤)。