2015-09-16 78 views
-3

隨着線程數量的增加,「temp」的計數值減少。 當我將線程數量發送爲「1」時,它會給出正確的答案,但隨着線程數量的增加,運行時間較短,但給出錯誤的答案OpenMP和MPI混合動態調度

#include <stdio.h> 
#include <mpi.h> 
#include <complex.h> 
#include <time.h> 
#include <omp.h> 

#define MAXITERS 1000 

// globals 
int count = 0; 
int nptsside; 
float side2; 
float side4; 
int temp = 0; 

int inset(double complex c) { 
    int iters; 
    float rl,im; 
    double complex z = c; 
    for (iters = 0; iters < MAXITERS; iters++) { 
     z = z*z + c; 
     rl = creal(z); 
     im = cimag(z); 
     if (rl*rl + im*im > 4) return 0; 
    } 
    return 1; 
} 

int main(int argc, char **argv) 
{ 
    nptsside = atoi(argv[1]); 
    side2 = nptsside/2.0; 
    side4 = nptsside/4.0; 

    //struct timespec bgn,nd; 
    //clock_gettime(CLOCK_REALTIME, &bgn); 

    int x,y; float xv,yv; 
    double complex z; 
    int i; 
    int mystart, myend; 
    int nrows; 
    int nprocs, mype; 
    int data; 


    MPI_Status status; 
    MPI_Init(&argc,&argv); 
    MPI_Comm_size(MPI_COMM_WORLD, &nprocs); 
    MPI_Comm_rank(MPI_COMM_WORLD, &mype); 
    nrows = nptsside/nprocs; 
    printf("%d\n", nprocs); 

    mystart = mype*nrows; 
    myend = mystart + nrows - 1; 


    #pragma omp parallel shared(mystart, myend, temp) 
    { 
    int nth = omp_get_num_threads(); 
    printf("%d\n", nth); 
    #ifdef STATIC 
    #pragma omp for reduction(+:temp) schedule(static) 
    #elif defined DYNAMIC 
    #pragma omp for reduction(+:temp) schedule(dynamic) 
    #elif defined GUIDED 
    #pragma omp for reduction(+:temp) schedule(guided) 
    #endif 
    for (x=mystart; x<=myend; x++) { 

    for (y=0; y<nptsside; y++) { 
     xv = (x - side2)/side4; 
     yv = (y - side2)/side4; 
     z = xv + yv*I; 
     if (inset(z)) { 
      temp++; 
     } 
    } 
    } 
    } 


    if(mype==0) { 
    count += temp; 
    printf("%d\n", temp); 

    for (i = 1; i < nprocs; i++) { 
     MPI_Recv(&temp, 1, MPI_INT, i, 0, MPI_COMM_WORLD, &status); 
     count += temp; 
     printf("%d\n", temp); 
     } 
     } 
     else{ 
     MPI_Send(&temp, 1, MPI_INT, 0, 0, MPI_COMM_WORLD); 
     } 



    MPI_Finalize(); 

    if(mype==0) { 
    printf("%d\n", count); 
    } 

    //clock_gettime(CLOCK_REALTIME, &nd); 
    //printf("%f\n",timediff(bgn,nd)); 
} 
+2

問題是? – lukelazarovic

+0

問題是爲什麼當線程數量增加時它給出了錯誤的答案...例如,如果線程數是「一個」..它給出了1000,但是當線程數量增加時,它會給出200或300正確的計數(溫度)是1000 –

回答

0

您還沒有定義,當你進入循環的OpenMP任何私有變量。

首先,您必須始終爲您的OpenMP循環聲明循環計數器(以及OpenMP循環中嵌套循環的任何循環計數器)。其次,你有三個變量(xv,yvz),每個變量都取決於你在這些循環中的迭代次數。因此,每個線程也需要擁有自己的這些變量的私有副本。改變你的並行語句爲

#pragma omp parallel shared(mystart, myend, temp) private(x, y, xv, yv, z) 

應該修復你的OpenMP問題。

看到你所說的將線程數設置爲1會產生正確的答案,我沒有看過你的MPI代碼。

編輯:好的我撒謊了,我簡單地看了看你的MPI代碼。而不是所有的發送和接收,你應該寫一個單一的減少。這個集體將比當前設置的阻止通信快得多。

MPI_Reduce(&temp, &count, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD); 
+0

非常感謝。..我還有一個問題。爲什麼添加更多的線程將減少大約一半的運行時間,但增加更多的進程不會像Openmp那樣減少運行時間..任何原因? –

+0

也許開發流程的開銷並不值得,因爲你做的工作很少。或者你最終做的交流比你想象的要多得多?我無法肯定地說。 – NoseKnowsAll