2012-03-12 75 views
1

如何將此代碼與OpenMP並行?我得到的結果是不正確的。使用openmp並行化c代碼問題

我嘗試使用臨時變量p1auxp2auxpsumaux,因爲Reduction子句不能用於指針或內部函數。但正如我所說的結果是不正確的。

當我說「結果不正確」時,我會說:array1 + array2的計算存儲在矩陣sumsse中。計算是正確的,直到組件sumsse[50] [50] [50]或多或少,但矩陣的其他組件始終爲0

你知道會發生什麼嗎?

如果有人能幫助我,非常感謝。

#include <stdio.h> 
#ifdef __SSE2__ 
#include <emmintrin.h> 
#endif 

#include <omp.h> 
#include <stdlib.h> 
#include <math.h> 

double __attribute__((aligned(16))) array1[256][256][256],array2[256][256][256]; 
double __attribute__((aligned(16))) sumsse[256][256][256]; 



int main() 
{ 

    int k,j,i,dim; 
    dim=256; 


    __m128d *p1= (__m128d*) &array1[0][0][0]; 
    __m128d *p2= (__m128d*) &array2[0][0][0]; 
    __m128d *psum= (__m128d*) &sumsse[0][0][0]; 

    __m128d *p1aux= (__m128d*) &array1[0][0][0]; 
    __m128d *p2aux= (__m128d*) &array2[0][0][0]; 
    __m128d *psumaux= (__m128d*) &sumsse[0][0][0]; 

    int nthreads =(8); 
    omp_set_num_threads(nthreads); 


    //initializa array2 

    for(k = 0; k < dim; ++k){ 
     for(j = 0; j < dim; ++j){ 
      for(i = 0; i < dim; ++i){ 
       array2[k][j][i] = 1.0; 
      } 
     } 
    } 

    //initialize array1 

    for(k = 0; k < dim; ++k){ 
     for(j = 0; j < dim; ++j){ 
      for(i = 0; i < dim; ++i){ 
       array1[k][j][i] = i + j + k; 
      } 
     } 
    } 

    //initialize array sumsse 

    for(k = 0; k < dim; ++k){ 
     for(j = 0; j < dim; ++j){ 
      for(i = 0; i < dim; ++i){ 
       sumsse[k][j][i] = 0.0; 
      } 
     } 
    } 

    //add array1 + array2 with sse 

#pragma omp parallel firstprivate(p1,p2,p1aux,p2aux) 
    { 

    for(k = 0; k < dim; ++k){ 

     for(j = 0; j < dim; ++j){ 

#pragma omp for private(i) 

       for(i = 0; i < dim; i += 2){ 

        *psum = _mm_add_pd(*p1,*p2); 

        psum = psumaux + 1; 
        p1 = p1aux+1; 
        p2 = p2aux+1; 
        psumaux = psum; 
        p1aux = p1; 
        p2aux = p2; 
       } 
      } 
     } 

    }// end parallel 


    //show some datas 


    printf("Elementosse=10 sumsse=%f",sumsse[10][10][10]); 
    printf("\n"); 
    printf("Elementosse=50 sumsse=%f",sumsse[50][50][50]); 
    printf("Elementosse=100 sumsse=%f",sumsse[100][100][100]); 
    printf("\n"); 
    printf("Elementosse=120 sumsse=%f",sumsse[120][120][120]); 
    printf("\n"); 
    printf("Elementosse=200 sumsse=%f",sumsse[200][200][200]); 
    printf("\n"); 

    return 0; 
} 
+0

它看起來像你的第一個'#pragma'是錯誤的,'私人'關鍵字與私有變量列表分開。如果不是拼寫錯誤,它可以解釋爲什麼您的並行代碼不能按預期工作... – Francesco 2012-03-12 19:47:33

回答

1

,而不必增加您的輔助變量奇怪的是,你應該一個封閉的形式爲每個它在kjimax項指標的事情。那麼你應該確保它們之間沒有混淆。

+0

如何確保threre不會在它們之間混淆?你能給我一個例子嗎?非常感謝你 – user1264388 2012-03-19 12:08:03

+0

我的意思是,你應該詳細說明內部塊中indeces的封閉形式。然後你會看到哪個'for'循環最好放置在最外面,以使其內部的其餘循環都是獨立的。 – 2012-03-19 12:15:37

+0

你認爲沒有正確的結果不是因爲不使用還原條款嗎? – user1264388 2012-03-19 12:42:20