¿Multiplicación de matrices usando múltiples hilos?

Se supone que debo multiplicar 2 matrices usando hilos. Dos cosas: Sigo obteniendo 0 cuando ejecuto el progtwig. También recibo mensajes de error (para cada uno, dice “advertencia: pasa el argumento 1 de ‘printMatrix’ de un tipo de puntero incompatible” en las líneas en negrita (donde bash imprimir la salida). También para tener en cuenta, el primer bloque que está en negrita , Ese fue mi bash de resolver el problema. Creo que estoy cerca, pero puede que no lo esté. ¿Puede alguien ayudarme? Gracias 🙂 La salida se ve así: 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 0

#include  #include  #include  #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;ii = 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); } 

Su progtwig parece haber implementado un algoritmo de encoding incorrecto para la multiplicación de matrices.

El siguiente código parece absurdo:

 for(k=0; k 

Deberías implementar algo como:

 for(i=0;i 

FWIW … para una matriz pequeña, el costo de comenzar los subprocesos y lo que no es probable significa que todo esto es una pérdida de tiempo … ¡y para una matriz grande parece que está comenzando con hilos M * N!

Como podemos suponer que esto está vinculado a la computación, no tiene mucho sentido iniciar más subprocesos de los que hay CPU para usar. Luego, cada hilo debe seleccionar el siguiente elemento de resultado para calcular, y detenerse cuando el resultado esté completo. Una forma de hacerlo sería pasar una estructura de “control” a todos los subprocesos, siguiendo las líneas de:

  struct control { pthread_mutex_t mutex ; int q ; } ; 

y luego la función pthread haría un bucle:

  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 ; .... } ; 

Una búsqueda atómica y agregar 1 de q haría el trabajo también. (NB: se supone que N * M + número de subprocesos es <= INT_MAX!)

Por supuesto, podría dividir los resultados de N * M forma estática en función del número de pthreads que inicie, de modo que pase cada uno una q diferente y la cantidad de elementos de los resultados de los que es responsable (recuerde que debe tratar el rest después de dividir N * M por el número de pthreads!). Esto evita toda necesidad de que los pthreads interactúen, por lo que no se requieren mutex ni atómicos.

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