2012-03-12 2 views
1

Как я могу распараллелить этот код с помощью OpenMP ?. Результат, который я получаю, неверен.Проблема, распараллеливающая этот код с помощью openmp

Я пытаюсь использовать временные переменные p1aux, p2aux и psumaux, потому что предложение 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

похоже, что ваша первая '# прагма' неверна, а ключевое слово' private' отделено от списка личных переменных. Если это не опечатка, это может объяснить, почему ваш параллельный код работает не так, как ожидалось ... – Francesco

ответ

1

вместо того, увеличивается вашей вспомогательной переменной причудливо вы должны вещь закрытой формы для индекса каждого из него с точки зрения k, j, i и max. Тогда вы должны заверить, что между ними нет сглаживания.

+0

Как я могу заверить, что между ними нет слияния ?. Можете ли вы привести мне пример ?. Большое спасибо – user1264388

+0

Что я имел в виду, так это то, что вы должны разработать закрытые формы для indeces во внутреннем блоке. Затем вы увидите, какая из циклов 'for' лучше всего расположена снаружи, так что остальные петли внутри нее являются независимыми. –

+0

Считаете ли вы, что правильный результат не из-за того, что не используется пункт сокращения? – user1264388

Смежные вопросы