CODIGO FUENTE
#include"rshmem.h"
#include<time.h>
#include<stdlib.h>
/*** Definicion de la matriz ***/
typedef struct{
int fila,
columna;
float **elem;
}matriz;
/********************************************
* Funcion para reservar memoria compartida *
*********************************************/
matriz* reservar_memoria(int fila,int columna)
{
int i,
j,
k;
matriz *m; /* Puntero correspondiente a cada matriz */
extern char * memoria ; /* Puntero a la zona de memoria reservada */
m = (matriz *) memoria; /* Inicializacion de la matriz */
memoria += sizeof(matriz)+fila*sizeof(float *) + fila*columna*sizeof(float)+sizeof(int);
/* Damos formato a la memoria */
m->fila = fila;
m->columna = columna;
m->elem = (float **)&m->elem + sizeof(float **);
for(i=0;i<fila;i++)
m->elem[i] = (float*)&m->elem[fila]+i*columna*sizeof(float);
return m;
}
/***************************************
* Funcion para generar las matrices *
***************************************/
matriz* generar_matriz(int fila,int columna)
{
int i,j,num;
float u;
matriz *m;
time_t t;
/* Cambiamos la semilla del generador */
srand((unsigned)time (&t));
m=reservar_memoria(fila,columna);
/* Generamos los elementos de la matriz aleatoriamente */
for(i=0;i<fila;i++){
for(j=0;j<columna;j++){
num=rand();
u=(float)(num)/RAND_MAX;
num=(int)(u*10);
m->elem[i][j]=num;
}
}
return m;
}
/******************************************
* Funcion para multiplicar las matrices *
******************************************/
matriz * multiplicar_matrices(matriz *a,matriz *b,int n_lineas)
{
int p,
mutex, /* Semaforo */
n_proces; /* Numero de procesos */
matriz *c; /* Matriz producto */
key_t clavemutex; /* Clave del semaforo */
int *finProc ; /* Marcas de final de cada proceso */
/* Reservar memoria para la matriz producto */
c=reservar_memoria(a->fila,b->columna);
/*Obtenemos una clave cualquiera para el semaforo*/
if((key_t) -1 == (clavemutex = ftok ("practica", 's'))){
fprintf(stderr, "main: error al crear la clave \n");
exit(1);
}
/* Creamos 1 semaforo binario */
if( -1 ==( mutex=semCreate(clavemutex,1))){
fprintf(stderr,"main: error no pude crear el semaforo \n");
exit(1);
}
c->fila--;
n_proces=a->fila/n_lineas; /* Numero de procesos que creamos */
finProc = (int *) memoria ;
memoria += sizeof(int);
*finProc = 0;
for(p=0;p<n_proces;p++){
if(fork()==0){
/* Codigo para los procesos hijo */
int i,
j,
k,
z;
/* Asignacion de filas a cada proceso */
semWait(mutex);
i=c->fila;
c->fila-=n_lineas;
semSignal(mutex);
/* Calculo de la fila i_esima */
for(z=0;z<n_lineas;z++){
for(j=0;j<c->columna;j++){
c->elem[i][j]=0;
for(k=0;k<a->columna;k++)
c->elem[i][j]+=a->elem[i][k]*b->elem[k][j];
}
i--;
}
/* Fin de los procesos hijo */
semWait(mutex);
*finProc+=1;
semSignal(mutex);
exit(0);
}/* fin if */
}/* fin for */
/* El proceso padre espera a que terminen los hijos */
while (*finProc!=n_proces) ;
/* borramos el semaforo */
semClose(mutex);
c->fila=a->fila;
return c;
}
/**************************
* Funcion imprimir_matriz *
**************************/
imprimir_matriz(matriz *m, FILE *fich)
{
int i,
j;
for(i=0;i<m->fila;i++){
for(j=0;j<m->columna;j++)
fprintf(fich,"%14.3e ",m->elem[i][j]);
fprintf(fich,"\n");
}
}
imprimir_resultados(matriz *a,matriz *b,matriz *c,FILE *fich)
{
fprintf(fich,"La primera matriz es:\n");
imprimir_matriz(a, fich);
fprintf(fich,"\n\n");
fprintf(fich,"La segunda matriz es:\n");
imprimir_matriz(b, fich);
fprintf(fich,"\n\n");
fprintf(fich,"La matriz producto es:\n");
imprimir_matriz(c, fich);
}
/************************
* Funcion principal *
************************/
main(int argc,char **argv)
{
int n_lineas, /* Numero de lineas de la matriz producto que genera cada proceso */
f_a, /* Numero de filas de la primera matriz */
c_a, /* Numero de columnas de la primera matiz */
f_b, /* Numero de filas de la segunda matriz */
c_b; /* Numero de columnas de la segunda matriz */
matriz *a,*b,*c; /* Matrices */
FILE *fich; /* Puntero al fichero de salida */
if(argc!=6)
fprintf(stderr,"Error en el numero de argumentos \n");
f_a=atoi(*(argv+1));
c_a=atoi(*(argv+2));
f_b=atoi(*(argv+3));
c_b=atoi(*(argv+4));
n_lineas=atoi(*(argv+5));
if(c_a!=f_b){
fprintf(stderr,"Las matrices no se pueden multiplicar.\n");
exit(1);
}
if((f_a%n_lineas)!=0){
fprintf(stderr,"Error en el numero de lineas de cada proceso.\n");
exit(1);
}
/* Peticion de memoria compartida */
if(!crearMemoria()) {
fprintf(stderr,"Error al crear memoria compartida \n");
exit(1);
}
/* Crear las matrices */
a=generar_matriz(f_a,c_a);
b=generar_matriz(f_b,c_b);
c=multiplicar_matrices(a,b,n_lineas);
if((fich=fopen("salida","w+"))==NULL){
fprintf(stderr,"Error, no se pudo abrir el fichero de salida");
exit(1);
}
imprimir_resultados(a,b,c,fich);
fclose(fich);
/* eliminamos la memoria compartida */
if(!eliminarMemoria())
fprintf(stderr,"error al eliminar la memoria.\n");
exit(0);
}