Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: eberfalu2 en 25 Septiembre 2015, 00:24 am



Título: multiplicacion de matrices rectangulares con pthreads
Publicado por: eberfalu2 en 25 Septiembre 2015, 00:24 am
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.

Código
  1. #include <pthread.h>
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include "../include/matrix.h"
  5. #include "../include/parser.h"
  6.  
  7. #define FILEIN_1 "in1.txt"
  8. #define FILEIN_2 "in2.txt"
  9. #define FILEOUT "out.txt"
  10. #define NOF_ARGS 2
  11.  
  12. MATRIX *MAT_ONE, *MAT_TWO, *MAT_OUT; // global matrixes to operate upon
  13. int NOF_PROC; // number of processes passed as argument via terminal
  14.  
  15.  
  16. void *multiplica(void *id) {
  17. unsigned long threadId = (unsigned long) id;
  18. fprintf(stderr, "threadId: %lu\n",threadId);
  19. int i,j,k;
  20. for (i = (threadId*(MAT_ONE->r/NOF_PROC)); i < ((threadId+1)*(MAT_ONE->r/NOF_PROC)); i++)
  21.  for (j = 0; j < MAT_TWO->c; j++){
  22.    MAT_OUT->matrix[i][j] = 0;
  23.    for (k = 0; k < MAT_ONE->c; k++)
  24.      MAT_OUT->matrix[i][j] += MAT_ONE->matrix[i][k] * MAT_TWO->matrix[k][j];
  25.  }
  26. pthread_exit(NULL);
  27. }
  28.  
  29.  
  30. int main(int argc, char *argv[]) {
  31.  
  32. int i,j,k,flag;
  33.  
  34. if(argc == NOF_ARGS) {
  35. sscanf(argv[1], "%d", &NOF_PROC);
  36. if(NOF_PROC < 0) {
  37. fprintf(stderr, "ERROR: invalid number of processes.\n");
  38. exit(EXIT_FAILURE);
  39. }
  40. }
  41. else {
  42. fprintf(stderr,
  43. "ERROR: invalid number of arguments. EXPECTS n : integer.\n");
  44. exit(EXIT_FAILURE);
  45. }
  46.  
  47.  MAT_ONE = MATRIX_new(parser_rows(FILEIN_1), parser_cols(FILEIN_1));
  48.  parser_matrix(FILEIN_1, MAT_ONE);
  49.  
  50.  MAT_TWO = MATRIX_new(parser_rows(FILEIN_2), parser_cols(FILEIN_2));
  51.  parser_matrix(FILEIN_2, MAT_TWO);
  52.  
  53.  if(!(MATRIX_is_multipliable(MAT_ONE, MAT_TWO))) {
  54.    fprintf(stderr, "ERROR: invalid matrixes sizes.\n");
  55.    exit(EXIT_FAILURE);
  56.  }
  57.  
  58.   MAT_OUT = MATRIX_new(MAT_ONE->r, MAT_TWO->c);
  59.  
  60.    pthread_t threads[NOF_PROC];
  61.    pthread_attr_t atributos;
  62.    pthread_attr_init(&atributos);
  63.    pthread_attr_setdetachstate(&atributos, PTHREAD_CREATE_JOINABLE);
  64.    pthread_attr_setscope(&atributos,PTHREAD_SCOPE_SYSTEM);
  65.  
  66.  
  67.    for (i = 0; i < NOF_PROC; i++){
  68.      flag = pthread_create(&threads[i], NULL, multiplica, (void *) (unsigned long) i);
  69.      if (flag)
  70.        exit(-1);
  71.    }
  72.  
  73.    for (i = 0; i < NOF_PROC; i++)
  74.      pthread_join(threads[i], NULL);
  75.  
  76.      for(k = 0; k < (MAT_OUT->r); k++)
  77.      {
  78.         for(j = 0; j < MAT_OUT->c; j++)
  79.         {
  80.            printf("%d ",MAT_OUT->matrix[k][j]);
  81.         }
  82.      printf("\n");
  83.      }
  84.  
  85.      UTILS_write_matrix(FILEOUT, MAT_OUT);
  86.      MATRIX_free(MAT_ONE);
  87.      MATRIX_free(MAT_TWO);
  88.      MATRIX_free(MAT_OUT);
  89.  
  90. return 0;
  91. }
  92.  

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


Título: Re: multiplicacion de matrices rectangulares con pthreads
Publicado por: A.I. en 25 Septiembre 2015, 04:09 am
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).


Título: Re: multiplicacion de matrices rectangulares con pthreads
Publicado por: eberfalu2 en 25 Septiembre 2015, 19:37 pm
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..