使用多线程的矩阵乘法?

时间:2014-10-21 03:47:08

标签: c pthreads matrix-multiplication

我应该使用线程乘以2个矩阵。两件事:我在运行程序时一直都是0。我也得到了消息错误(对于每一个,它说"警告:从不兼容的指针类型"传递参数1' printMatrix'在粗体线上(我尝试打印输出)。还要注意,第一个加粗的块,我是我尝试解决问题。我想我很接近,但我可能不会。有人可以帮忙吗?谢谢:) 输出如下: A = 1 4 2 5 3 6 B = 8 7 6 5 4 3 A * B = 0 0 0 0 0 0 0 0 0

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>

#define M 3
#define K 2
#define N 3

struct v
{
    int i; //row
    int j; //column
};

int A[M][K] = {{1,4},{2,5},{3,6}};
int B[K][N] = {{8,7,6},{5,4,3}};
int C[M][N];

void *workerThread(void *data)
{
    int i=((struct v*)data)->i;
    int j=((struct v*)data)->j;
    int accumulator = 0;

/*this is where you should calculate the assigned Cell. You will need to use the row(i) of
            A and column[j] of B. Accumulate the result in accumulator */
    **int k;
    for(k=0; k<k; k++)
    {
            accumulator = A[i][k]*B[k][j];
    }
    C[i][j]=accumulator;
    pthread_exit(NULL);**
 }

 void printMatrix(int *matrixIn, int rows, int columns)
{
    int *matrix = matrixIn;
    int i,j;
    for (i=0;i<rows;i++)
    {
}

int main (int argc, char *argv[])
{

    pthread_t threads[M*N];
    int i,j;
    int counter = 0;
    int numThreadsCreated = 0;

    /*the following 5 lines demonstrates how to create 1 thread to calculate C[0][0], you
            will need to create a loop for all of C's cells*/
    struct v *data = (struct v *)malloc(sizeof(struct v));
    data->i = 0; //assign the row of C for thread to calculate
    data->j = 0; //assign the column of C for thread to calculate
    pthread_create(&threads[0], NULL, workerThread, data);
    numThreadsCreated++;

    /*wait for all the threads to finish before printing out the matrices*/
    for(j=0; j < numThreadsCreated; j++)
    {
            pthread_join( threads[j], NULL);
    }

    printf("A=\n");
    **printMatrix(A,3,2);**
    printf("B=\n");
    **printMatrix(B,2,3);**
    printf("A*B=\n");
    **printMatrix(C,M,N);**
    pthread_exit(NULL);
}

3 个答案:

答案 0 :(得分:1)

您的程序似乎已经实现了错误的矩阵乘法编码算法。

以下代码似乎很荒谬: -

for(k=0; k<k; k++)
{
        accumulator = A[i][k]*B[k][j];
}
C[i][j]=accumulator;    //   Not a code for matrix multiplication...

你应该实现类似的东西: -

for(i=0;i<M;i++){
 for(j=0;j<N;j++){
  accumulator=0;
   for(int something=0;something<K;something++){
    accumulator=accumulator+A[i][something]*B[something][j];
   }
  C[i][j]=accumulator;
  accumulator=0;
 }
}

答案 1 :(得分:0)

FWIW ...对于一个小矩阵,启动线程的成本和什么不可能意味着这都浪费时间......对于一个大矩阵,你似乎是在启动M * N个线程!

由于我们可能认为这是计算绑定的,因此启动更多线程的点数并不比要使用的CPU多。然后每个线程需要选择要计算的下一个结果项,并在结果满时停止。一种方法是将“控制”结构传递给所有pthreads,顺序为:

  struct control
  {
     pthread_mutex_t   mutex ;
     int  q ;
  } ;

然后pthread函数将循环:

  while (1)
    {
       int q, i, j ;

       pthread_mutex_lock(&ctrl->mutex) ;
       q = ctrl->q ;
       ctrl->q += 1 ;
       pthread_mutex_unlock(&ctrl->mutex) ;

       if (q >= (N * M))
         break ;

       i = q / K ;
       j = q % K ;

       ....
    } ;

原子获取和q的加1也可以完成这项工作。 (注意:假设N * M +线程计数是&lt; = INT_MAX!)

当然,您可以将N * M结果静态划分为您开始的pthread数量,因此将每个结果传递给不同的初始q以及它负责的结果项数(记住在将N * M除以pthreads之后处理余数!)。这避免了对pthreads进行交互的所有需求 - 因此不需要互斥体和原子。

答案 2 :(得分:0)

#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
#include<unistd.h>

pthread_mutex_t lock;

typedef struct
{

    int mat1;

    int mat2;
}address;

int matrix1[3][3],matrix2[3][3],result[3][3];

void *matrixOne()

{

    int i,j,data=0;

    for(i=0;i<3;i++)

    {

        for(j=0;j<3;j++)

        {

            matrix1[i][j]=data+1;

            //          sleep(2);

            data=data+1;

        }

    }

    //printf matrix

    printf("\n****matrix 1 created By thread-1***\n\n");

    for(i=0;i<3;i++)
    {
        printf("\n");
        for(j=0;j<3;j++)

        {

            printf("Element matrix[%d][%d] of matrixOne = %d\n",i,j,matrix1[i][j]);

            sleep(1);

        }
    }

    printf("\n**********1st matrix*********\n");

    for(i=0;i<3;i++)
    {
        printf("\n");
        for(j=0;j<3;j++)

        {

            printf(" %d ",matrix1[i][j]);

        }
    }



}
void *matrixTwo()

{

    int i,j,data=9;

    for(i=0;i<3;i++)

    {

        for(j=0;j<3;j++)

        {

            matrix2[i][j]=data;

            //          sleep(2);

            data=data-1;

        }

    }

    //printf matrix

    printf("\n\t\t\t\t\t****matrix 2 created By thread-2***\n");

    for(i=0;i<3;i++)
    {
        printf("\n");
        for(j=0;j<3;j++)

        {

            printf("\t\t\t\t\tElement matrix[%d][%d] of matrixTwo = %d\n",i,j,matrix2[i][j]);

            sleep(1);

        }
    }

    printf("\n**********2nd matrix*********\n");

    for(i=0;i<3;i++)
    {
        printf("\n");
        for(j=0;j<3;j++)

        {

            printf(" %d ",matrix2[i][j]);

        }
    }

    printf("\n");

}

void *multiply(void *data)

{
    pthread_mutex_lock(&lock);
    int i,j,k,sum=0;

    address *data1=(address*)data;

    for(i=0;i<1;i++)

    {

        for(j=0;j<3;j++)

        {

            sum=0;
            data1->mat2=0;
            for(k=0;k<3;k++)

            {

                //printf("%d\n",data1->mat1[i][k]);

                //              sum=sum+matrix1[i][k]*matrix2[k][j];

                sum=sum+(matrix1[data1->mat1][k])*(matrix2[data1->mat2][j]);

                ++(data1->mat2);

            }

            result[data1->mat1][j]=sum;
            //data1->mat2=0;

        }



    }

    printf("\n**********thread %d multiplication of matrix*********\n",data1->mat1);

    for(i=0;i<1;i++)
    {
        printf("\n");
        for(j=0;j<3;j++)

        {

            printf(" %d ",result[data1->mat1][j]);

        }
    }

    printf("\n");


    pthread_mutex_unlock(&lock);
}



void main()

{      

    int i,j;

    //      address add[3];


    address *add = (address*) malloc(3 * sizeof(address));


    pthread_t thread1,thread2,thread3[3];


    pthread_create(&thread1,NULL,matrixOne,NULL);

    //pthread_join(thread1,NULL);

    pthread_create(&thread2,NULL,matrixTwo,NULL);

    pthread_join(thread1,NULL);

    pthread_join(thread2,NULL);

    for(i=0;i<3;i++)

    {
        //  add[i].mat1=*matrix1+i*3*4;

        //  add[i].mat2=*matrix2+i*4;

        add[i].mat1=i;

        add[i].mat2=i;



        pthread_create(&thread3[i],NULL,multiply,&add[i]);

    }

    for(i=0;i<3;i++)

    {

        pthread_join(thread3[i],NULL);

    }

    printf("\n\n********** multiplication of matrix*********\n");

    for(i=0;i<3;i++)
    {
        printf("\n");
        for(j=0;j<3;j++)

        {

            printf(" %d ",result[i][j]);

        }
    }


    printf("\n\n");


}