问题
I am supposed to multiply 2 matrices using threads. Two things: I keep getting 0's when I run the program. I also get message errors(for each, it says "warning: passing argument 1 of 'printMatrix' from incompatible pointer type" on the bolded lines(where I try to print the output). Also to note, the first block that is bolded, I that was my attempt at solving the problem. I think I am close, but I may not be. Can anyone help? Thanks :) Output looks like this: 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);
}
回答1:
Your program seems to have implemented a wrong coding algorithm for matrix multiplication.
The following piece of code seems absurd :-
for(k=0; k<k; k++)
{
accumulator = A[i][k]*B[k][j];
}
C[i][j]=accumulator; // Not a code for matrix multiplication...
You should implement something like :-
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;
}
}
回答2:
FWIW... for a small matrix the cost of starting threads and what-not is likely to mean this is all a waste of time... and for a large matrix you appear to be starting M*N threads !!
Since we may assume that this is compute-bound, there is not much point starting more threads than there are CPUs to use. Then each thread needs to select the next result item to calculate, and stop when the result is full. One way to do that would be to pass a "control" structure to all the pthreads, along the lines of:
struct control
{
pthread_mutex_t mutex ;
int q ;
} ;
and then the pthread function would loop:
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 ;
....
} ;
An atomic fetch and add 1 of q
would do the job as well. (NB: assumes that N*M + thread-count is <= INT_MAX !)
You could, of course, divide the N * M
results statically across the number of pthreads you start, so pass each one a different initial q
and the number of result items for which it is responsible (remembering to deal with the remainder after dividing N * M
by the number of pthreads !). This avoids all need for the pthreads to interact -- so no mutex and no atomics required.
回答3:
#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");
}
来源:https://stackoverflow.com/questions/26478552/matrix-multiplication-using-multiple-threads