multiplicacion de matrices rectangulares con pthreads

Iniciado por eberfalu2, 25 Septiembre 2015, 00:24 AM

0 Miembros y 1 Visitante están viendo este tema.

eberfalu2

Hola gente, estoy un poco perdido, desarrolle un codigo C para multiplicacion de matrices con pthreads pero solo sirve para cuando las matrices son cuadradas o la cantidad de columnas son multiplos de la cantidad de hilos que le paso por argunmento, lo que tengo que desarrollar tiene que ser para cualquier matriz dada, pasando por argumento la cantidad de hilos.


#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include "../include/matrix.h"
#include "../include/parser.h"

#define FILEIN_1 "in1.txt"
#define FILEIN_2 "in2.txt"
#define FILEOUT "out.txt"
#define NOF_ARGS 2

MATRIX *MAT_ONE, *MAT_TWO, *MAT_OUT; // global matrixes to operate upon
int NOF_PROC; // number of processes passed as argument via terminal


void *multiplica(void *id) {
unsigned long threadId = (unsigned long) id;
fprintf(stderr, "threadId: %lu\n",threadId);
int i,j,k;
for (i = (threadId*(MAT_ONE->r/NOF_PROC)); i < ((threadId+1)*(MAT_ONE->r/NOF_PROC)); i++)
 for (j = 0; j < MAT_TWO->c; j++){
   MAT_OUT->matrix[i][j] = 0;
   for (k = 0; k < MAT_ONE->c; k++)
     MAT_OUT->matrix[i][j] += MAT_ONE->matrix[i][k] * MAT_TWO->matrix[k][j];
 }
pthread_exit(NULL);
}


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

int i,j,k,flag;

if(argc == NOF_ARGS) {
sscanf(argv[1], "%d", &NOF_PROC);
if(NOF_PROC < 0) {
fprintf(stderr, "ERROR: invalid number of processes.\n");
exit(EXIT_FAILURE);
}
}
else {
fprintf(stderr,
"ERROR: invalid number of arguments. EXPECTS n : integer.\n");
exit(EXIT_FAILURE);
}

 MAT_ONE = MATRIX_new(parser_rows(FILEIN_1), parser_cols(FILEIN_1));
 parser_matrix(FILEIN_1, MAT_ONE);

 MAT_TWO = MATRIX_new(parser_rows(FILEIN_2), parser_cols(FILEIN_2));
 parser_matrix(FILEIN_2, MAT_TWO);

 if(!(MATRIX_is_multipliable(MAT_ONE, MAT_TWO))) {
   fprintf(stderr, "ERROR: invalid matrixes sizes.\n");
   exit(EXIT_FAILURE);
 }

  MAT_OUT = MATRIX_new(MAT_ONE->r, MAT_TWO->c);

   pthread_t threads[NOF_PROC];
   pthread_attr_t atributos;
   pthread_attr_init(&atributos);
   pthread_attr_setdetachstate(&atributos, PTHREAD_CREATE_JOINABLE);
   pthread_attr_setscope(&atributos,PTHREAD_SCOPE_SYSTEM);


   for (i = 0; i < NOF_PROC; i++){
     flag = pthread_create(&threads[i], NULL, multiplica, (void *) (unsigned long) i);
     if (flag)
       exit(-1);
   }

   for (i = 0; i < NOF_PROC; i++)
     pthread_join(threads[i], NULL);

     for(k = 0; k < (MAT_OUT->r); k++)
     {
        for(j = 0; j < MAT_OUT->c; j++)
        {
           printf("%d ",MAT_OUT->matrix[k][j]);
        }
     printf("\n");
     }

     UTILS_write_matrix(FILEOUT, MAT_OUT);
     MATRIX_free(MAT_ONE);
     MATRIX_free(MAT_TWO);
     MATRIX_free(MAT_OUT);

return 0;
}


Pero ahora no se como modificarlo para poder hacerlo para cualquier tipo de matriz rectangular.
gracias!

A.I.

El problema es que no puedes asignar un número de columnas que no sea múltiplo de tu número de hilos de forma totalmente equitativa entre ellos (que es lo que intenta hacer tú código).  Como lo tienes siempre que no sea múltiplo se van a quedar sin procesar entre 1 e hilos-1 filas.

La solución más sencilla es detectar ésto en el hilo que más te guste y procesar esas filas en él.
Si fuesen demasiados hilos o el tiempo necesario para procesar una fila demasiado alto: detectarlo y repartirlas.

Como detalle, utilizar más hilos que cores no suele reportar ningún beneficio, más bien al contrario. Además si no son matrices bastantes grandes tampoco notarás aceleración con respecto a un código secuencial. Sí sólo lo haces para practicar hilos bien, si aspiras hacer esto con matrices inmensas en maquinas chulas mírate cosas cómo omp o mpi (dependiendo del tipo de máquina).

eberfalu2

Gracias por la respuesta, ahora tengo una segunda version con Mutex, pero tengo algunos problemas, pero esta mucho mejor, gracias por las recomendaciones, la idea es para matrices bien grandes y probarlo en una pc de 8cores pero es solo un laboratorio de la facultad para practiar hilos por lo que si o si lo tengo que desarrolar con eso..