0

Openmpを使用してタスクを4つのスレッドに分散させたい。私は20x20のマトリックスを持っており、プログラムが間違った結果を出すと、タスクは4つのスレッドに均等に分散されるはずです。forループでパラメータを変更する必要があると思います。誰か助けてくれますか。

#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); 
    }   
4

3 に答える 3

0

各スレッドは、対角線の周りに25個の値しか生成していません。それはあなたが意図したことですか?マトリックスには400のエントリがありますが、実際には4 * 25 = 100のエントリしか初期化していないため、最後のプリントアウトは対角線の周りを除いてほとんどゴミになります。

すべてのスレッドもsumロック/同期なしで変数にアクセスしているため、合計から読み取った値は完全に非決定的です。

本当にmatrix*matrix multiplyを書くつもりなら、最初に書くつもりの三重にネストされたループを書くべきです。おそらく次のようなものです:

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

次に、最も外側のループを4つのスレッドに分割します。

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

または、openMPで作業を分割することをお勧めします。(私はopenMPの専門家ではありませんが、これがあなたのやり方だと思います。)

#pragma omp parallel
{
  #pragma omp for
  for (int i=0; i<20; i++) {
    for (int j=0; j<20; j++) {
      ...
}
于 2013-03-26T11:51:17.123 に答える
0

この関数を使用します。floatを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;
        }
    }
}
于 2013-03-26T14:55:48.350 に答える
0

ワンダリングログインでは単一のforループを使用して機能するため、4つのスレッドを使用してこれを行う必要がありますが、4つのスレッド間でタスクをデバイス化したいです.Raxmanに従って変更を加えましたが、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); 
}   
于 2013-03-29T03:29:38.433 に答える