2013-03-26 3 views
0

OpenMP를 사용하여 4 개의 스레드간에 작업을 배포하려고합니다. 나는 20x20 매트릭스와 작업이 4 개의 스레드 사이에 똑같이 분산되어야하며, 잘못된 결과를주는 프로그램을 따라야한다. for 루프에서 매개 변수를 변경해야한다고 생각합니다. 어느 누구도 나를 도와 줄 수 없습니다.openmp에서 여러 스레드간에 작업을 배포하는 방법은 무엇입니까?

#include<stdio.h> 
    #include<omp.h> 
    #include "head.h" 
    //int sum=0; 
    int c[20][20]; 
    //#include<conio.h> 
     int main(void) { 
      int A[20][20],B[20][20],C[20][20]; 
      int i; 
      static int j,e; 
      static sum=0; 
      FILE *fp; 
      unsigned long long a,b,c,d; 

      int threadno; 
      fp=fopen("m2.txt","w"); 
      // printf("\n%d \n",h[20][20]); 
       #pragma omp parallel shared(a,b,c,d) 
      { 
      threadno=omp_get_thread_num(); 

      if(threadno==0) 
      {  
       for (i=0;i<5;i++) 
       { 
       for (j=0;j<5;j++) 
       { 
        A[i][j]=i*j; 
        B[i][j]=i*j; 
       } 
       } 

       for (i=0;i<5;i++) 
       { 
       for (j=0;j<5;j++) 
       { 
        for (e=0;e<5;e++) 
        { 
        sum+=A[i][e]*B[e][j]; 
          C[i][j]=sum; 
        } 
       } 
       } 
      } 

      else if(threadno==1) 
      { 
       for (i=5;i<10;i++) 
       { 
       for (j=5;j<10;j++) 
       { 
        A[i][j]=i*j; 
        B[i][j]=i*j; 
       } 
       } 

       for (i=5;i<10;i++) 
       { 
       for (j=5;j<10;j++) 
       { 
        for (e=5;e<10;e++) 
        { 
        sum+=A[i][e]*B[e][j]; 
          C[i][j]=sum; 
        } 
       } 
       } 
      } 


      else if(threadno==2) 
      { 
       for (i=10;i<15;i++) 
       { 
       for (j=10;j<15;j++) 
       { 
        A[i][j]=i*j; 
        B[i][j]=i*j; 
       } 
       } 

       for (i=10;i<15;i++) 
       { 
       for (j=10;j<15;j++) 
       { 
        for (e=10;e<15;e++) 
        { 
        sum+=A[i][e]*B[e][j]; 
          C[i][j]=sum; 
        } 
       } 
       } 
      } 

      else if(threadno==3) 
      { 
       for (i=15;i<20;i++) 
       { 
       for (j=15;j<20;j++) 
       { 
        A[i][j]=i*j; 
        B[i][j]=i*j; 
       } 
       } 

       for (i=15;i<20;i++) 
       { 
       for (j=15;j<20;j++) 
       { 
        for (e=15;e<20;e++) 
        { 
        sum+=A[i][e]*B[e][j]; 
          C[i][j]=sum; 
        } 
       } 
       } 
      }  

      for (i=0;i<20;i++){ 
       for (j=0;j<20;j++) { 
        fprintf(fp,"%d \t",C[i][j]); 
       } 
      } 
    } 
    fclose(fp); 
    } 

답변

0

각 스레드는 대각선 주위로 25 개의 값만 생성합니다. 그게 당신이 의도 한 것입니까? 행렬에는 400 개의 항목이 있지만 실제로는 4 * 25 = 100 개만 초기화하므로 끝에있는 인쇄물은 대각선을 제외하고는 거의 쓰레기가됩니다.

모든 스레드는 잠금/동기화없이 변수 sum에도 액세스하므로 합계로 읽은 값은 완전히 비 결정적입니다.

실제로 행렬 * 행렬 곱셈을 쓰려면 다음과 같이 작성해야하는 3 중첩 루프를 먼저 작성해야합니다. 아마도 같은 :

for (int i = 5*omp_get_thread_num(); i < 5*(omp_get_thread_num()+1); i++) { 
    for (int j=0; j<20; j++) { 
    ... 

또는 더 나은이 OpenMP를 당신을 위해 일을 분할 :

for (int i=0; i<20; i++) { 
    for (int j=0; j<20; j++) { 
    for (int e=0; e<20; e++) { 
     // some work 
    } 
    } 
} 

그런 다음 4 개 스레드 사이의 바깥 쪽 루프를 나눕니다. (저는 OpenMP 전문가가 아닙니다.하지만이 방법을 사용하는 것이 좋습니다.)

#pragma omp parallel 
{ 
    #pragma omp for 
    for (int i=0; i<20; i++) { 
    for (int j=0; j<20; j++) { 
     ... 
} 
0

이 기능을 사용하십시오. 부동 소수점을 int로 변경하십시오.

void matrix_mult_scalar_openmp(const float*A , const float* B, float* C, const int N, const int M, const int K) { 
    #pragma omp parallel for 
    for(int i=0; i<N; i++) { 
     for(int j=0; j<K; j++) { 
      float tmp = 0; 
      for(int l=0; l<M; l++) { 
       tmp += A[M*i+l]*B[K*l+j]; 
      } 
      C[K*i + j] = tmp; 
     } 
    } 
} 
0

내가 루프에 대한 단일 사용하여 작동 로그인을 방황에 따라, 4 개 스레드를 사용하여이 작업을 수행하는 데 필요한,하지만 난 thread.I가 Raxman에 따라, 변경 한 4 중 장치 작업하려는 일부 코드는 unchanges입니다 왜냐하면 여기서 4 개의 스레드를 사용해야하기 때문입니다. 수정 된 코드 :

#include<stdio.h> 
#include<omp.h> 
#include "head.h" 
//int sum=0; 
int c[20][20]; 
//#include<conio.h> 
    int main(void) { 
     int A[20][20],B[20][20],C[20][20]; 
     int i; 
     static int j,e; 
     int sum; 
     FILE *fp; 
     unsigned long long a,b,c,d; 

     int threadno; 
     fp=fopen("m2.txt","w"); 
     for (i=0;i<20;i++) 
      { 
      for (j=0;j<20;j++) 
      { 
       A[i][j]=i*j; 
       B[i][j]=i*j; 
      } 
      } 
     // printf("\n%d \n",h[20][20]); 
      #pragma omp parallel shared(a,b,c,d) 
     { 
     threadno=omp_get_thread_num(); 



     if(threadno==0) 
     {  


      for (i=0;i<5;i++) 
      { 
      for (j=0;j<5;j++) 
      { 
       sum=0; 
       for (e=0;e<5;e++) 
       { 
       sum+=A[i][e]*B[e][j]; 
//       C[i][j]=sum; 
       } 
      C[i][j]=sum; 
      } 
      } 
     } 

     else if(threadno==1) 
     { 
    /*  for (i=5;i<10;i++) 
      { 
      for (j=5;j<10;j++) 
      { 
       A[i][j]=i*j; 
       B[i][j]=i*j; 
      } 
      }*/ 

      for (i=5;i<10;i++) 
      { 
      for (j=5;j<10;j++) 
      { 
       sum=0; 
       for (e=5;e<10;e++) 
       { 
       sum+=A[i][e]*B[e][j]; 
       //  C[i][j]=sum; 
       } 
      C[i][j]=sum; 
      } 
      } 
     } 


     else if(threadno==2) 
     { 
      /* for (i=10;i<15;i++) 
      { 
      for (j=10;j<15;j++) 
      { 
       A[i][j]=i*j; 
       B[i][j]=i*j; 
      } 
      }*/ 

      for (i=10;i<15;i++) 
      { 
      for (j=10;j<15;j++) 
      { 
       sum=0; 
       for (e=10;e<15;e++) 
       { 
       sum+=A[i][e]*B[e][j]; 
        } 
      C[i][j]=sum; 
      } 
      } 
     } 

     else if(threadno==3) 
     { 
     /* for (i=15;i<20;i++) 
      { 
      for (j=15;j<20;j++) 
      { 
       A[i][j]=i*j; 
       B[i][j]=i*j; 
      } 
      }*/ 

      for (i=15;i<20;i++) 
      { 
      for (j=15;j<20;j++) 
      { 
       sum=0; 
       for (e=15;e<20;e++) 
       { 
       sum+=A[i][e]*B[e][j]; 
         //C[i][j]=sum; 
       } 
      C[i][j]=sum; 
      } 
      } 
     }  

     for (i=0;i<20;i++){ 
      for (j=0;j<20;j++) { 
       fprintf(fp,"%d \t",C[i][j]); 
      } 
     } 
} 
fclose(fp); 
} 
관련 문제