0

我想使用 Openmp 在四个线程之间分配任务。我有 20x20 矩阵,任务应该平均分布在四个线程中,以下程序给出错误结果。我认为它需要在 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

我必须使用 4 个线程来执行此操作,根据漫游登录,它使用单个 for 循环工作,但我想在 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 回答
0

使用此功能。将浮点数更改为整数。

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

每个线程仅在对角线周围产生 25 个值。那是你的意图吗?您的矩阵有 400 个条目,但实际上您只初始化了 4*25 = 100 个条目,因此除了对角线周围之外,最后的打印输出大部分都是垃圾。

您的所有线程也在访问该变量sum而没有任何锁定/同步,因此您从 sum 中读取的值是完全不确定的。

如果您真的打算编写矩阵*矩阵乘法:那么您应该首先编写您打算编写的三重嵌套循环。也许是这样的:

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 回答