Sie sind auf Seite 1von 13

Multiplicacin de Matrices con Pthreads, OpenMP y MPI

Roxana Luque

Nelson Molinas

Ingeniera en Informtica
Facultad Politcnica
Universidad Nacional de Asuncin
San Lorenzo, Paraguay

Ingeniera en Informtica
Facultad Politcnica
Universidad Nacional de Asuncin
San Lorenzo, Paraguay

roxanalu@gmail.com

nelson.molinas@gmail.com

RESUMEN

Seales y manejadores de seales (signal handlers)

En este trabajo, se propone la implementacin de algoritmos que


realizan la multiplicacin paralela de matrices cuadradas
utilizando Pthreads, OpenMP y MPI. As mismo, se presentan
los resultados de algunas pruebas llevadas a cabo para analizar
el rendimiento de cada algoritmo.

El directorio actual de trabajo

ID del usuario y del grupo

Palabras Claves
Pthread, OpenMP, MPI, matrices.

1.

INTRODUCCIN

En programas de cmputo numrico es muy comn


encontrar tareas que pueden ser realizadas en paralelo [1]. Para
estos casos resulta muy til lanzar threads y as realizar el
procesamiento en paralelo. En particular, se analiza el caso de
un programa de multiplicacin de matrices cuadradas en
lenguaje C utilizando las libreras Pthread, OpenMP y MPI. Las
dos primeras libreras estn basadas en el paradigma de
memoria compartida y la ltima en el paso de mensajes.
Los algoritmos de matrices, y entre ellos los de
multiplicacin de matrices, han encontrado numerosas
aplicaciones en la resolucin de problemas tanto numricos,
como aquellos que no son numricos. La facilidad con que se
puede particionar el problema de multiplicar dos matrices
cuadradas, lo convierten en un candidato ideal para estudiar los
conceptos de computacin paralela, y permiten que sea fcil
formular algoritmos que aprovechen los recursos de un entorno
paralelo.
El documento se divide en diversas secciones,
primeramente se da una breve introduccin a las libreras, a
continuacin una comparacin entre ellas y por ltimo los
resultados experimentales, conclusiones, referencias y como
anexo los cdigos fuentes.

2.

PTHREADS

Los hilos comparten un espacio de memoria comn y con


frecuencia son programados (scheduled) dentro de un solo
proceso, de forma que se evitan un montn de las ineficiencias
de mltiples procesos [2].
Los hilos en un mismo proceso comparten:

Instrucciones del proceso

La mayor parte de los datos

Archivos abiertos (descriptores o descriptors)

Pthreads es un conjunto de interfaces para hilos desarrolladas


por el IEEE, que a cargo de la especificacin de un sistema
operativo portable (Portable Operating System Interface POSIX). La P en Pthreads significa POSIX y, de hecho, en
ocasiones a Pthreads se le llama hilos POSIX. En esencia, el
comit POSIX define un conjunto bsico de funciones y
estructuras de datos que se espera que sea aprobado por los
numerosos vendedores para que el cdigo de hilos pueda ser
portado fcilmente a travs de los sistemas operativos. El sueo
de la comisin fue concebido por los vendors de UNIX que en
su mayora implementaron Pthreads. (La excepcin notable es
Sun, que sigue prefiriendo a los hilos Solaris* como su principal
API de hilos). La portabilidad de Pthreads se ha ampliado an
ms por la adopcin de Linux y un puerto para plataformas
Windows.
Pthread esta definido como un conjunto de tipos y llamados a
procedimientos del lenguaje C, implementado en el encabezado
del archivo va include con pthread.h, que es la librera que nos
pone a disposicin todos los tipos y procedimientos para usar
hilos en un programa.

2.1

Implementacin con Pthreads

Para realizar la implementacin con Pthreads se modific la


funcin que multiplica matrices para que recorra la primera
matriz desde y hasta unas filas pasadas como parmetro.
Tambin se tuvo que modificar el cdigo que invocaba a esa
funcin para que cree los threads invocando para cada uno de
ellos a la funcin que realiza el producto con una parte distinta
de la matriz.
Se utiliz el Compilador gcc y la librera Pthreads de Linux para
compilar y ejecutar el programa.

3.

OPENMP

Con OpenMP [4], los threads son distribuidos y ejecutados en


diferentes procesadores, reduciendo el tiempo de ejecucin
haciendo que ms ciclos de procesos estn disponibles por
unidad de tiempo. Los resultados de cada ejecucin de threads
pueden luego ser combinados. Un usuario puede establecer los
nmeros de threads creados para regiones paralelas.
OpenMP es una interfaz de programacin de aplicaciones (API)
para la programacin multiproceso de memoria compartida en
mltiples plataformas. Permite aadir concurrencia a los

programas escritos en C, C++ y Fortran sobre la base del


modelo de ejecucin fork-join. Est disponible en muchas
arquitecturas, incluidas las plataformas de Unix y de Microsoft
Windows. Se compone de un conjunto de directivas de
compilador, rutinas de biblioteca, y variables de entorno que
influencian el comportamiento en tiempo de ejecucin.

3.1

Implementacin con OpenMP

Para la implementacin de la multiplicacin de matrices con


OpenMP se propone una estrategia que consiste en asignar un
nmero de filas de la primer matriz a cada thread para que cada
uno se encargue nicamente de ellas.
Para hacer que OpenMP distribuya el programa de
multiplicacin de matrices entre multiples threads solo hace
falta agregar justo antes del cdigo del ciclo principal de la
multiplicacin una directiva para que el compilador se encargue
de todo. Esto facilita muchsimo la programacin, ya que no hay
que modificar el cdigo para que maneje los threads, sino que
toda la preocupacin esta en programar bien el algoritmo,
dejando para OpenMP el trabajo de la creacin y administracin
de los threads.
Se utiliz el Compilador gcc y la librera OpenMP de Linux
para compilar y ejecutar el programa.

4.

MPI

MPI no es un nuevo leguaje de programacin, es una librera de


funciones a la que podemos llamar desde C Fortran. Esta
basada en paso de mensajes, la forma ms potente y aceptada
para programar sistemas paralelos y permite abstraer la gran
cantidad de detalles que la programacin paralela conlleva. Su
ventaja ms inmediata es su implementacin y portabilidad a
una gran variedad de sistemas: desde mquinas con memoria
compartida (Origin2000) hasta una red de estaciones de trabajo
[6].
Aunque existen otros enfoques de la programacin en paralelo
(directivas de memoria compartida, como OpenMP), el paso de
mensajes es considerado por algunos como el ensamblador de la
programacin paralela, por el grado de acercamiento a la
estructura paralela de nuestro programa, mantenindonos a salvo
de los problemas de implementacin en cada tipo de mquina.
Ejecutando un programa en MPI, cada procesador tiene una
copia de nuestro programa. Todos los procesadores comienzan a
ejecutar el mismo listado del programa, pero cada proceso
ejecutar distintas sentencias del programa, por bifurcaciones
introducidas basadas en el rango del proceso (el rango identifica
a cada proceso). De esta forma, cada procesador ejecuta el
mismo programa, pero har diferentes cosas dependiendo del
procesador donde se ejecuta.

4.1

Implementacin con MPI

Para la implementacin de multiplicacin de matrices tenemos


un proceso maestro, el cual distribuye las distintas tareas al resto
de procesos y varios procesos worker quienes calculan un cierto
nmero de filas de la matriz resultante y reenva el resultado
parcial al proceso maestro.
Se utiliz el Compilador gcc y la librera MPI de Linux para
compilar y ejecutar el programa.

5.
OPENMP VERSUS PTHREAD
VERSUS MPI
Se diferencian principalmente en el comportamiento en el nivel
de control que se quiere sobre la paralelizacin. OpenMP es
buensimo si todo lo que se necesita hacer es colocar algunas
directivas #pragma para tener una versin paralela de un cdigo
serial rpidamente. Ahora para realizar cosas ms interesantes
como codificacin de colas complejas, se puede utilizar
OpenMP pero sera ms directa y fcil la utilizacin de Pthreads
[5].
OpenMP provee caractersticas reducidas, es decir se consigue
muchas funcionalidades con mucho menos trabajo.
OpenMP es mucho alto nivel de Pthread. Es fcil de usar, basta
con aadir algunas directivas. Por otro lado, Pthread le da ms
control de su cdigo y se puede aprender y entender lo que est
sucediendo en un algoritmo paralelo.
Las directivas #pragma de OpenMP tienen otra ventaja clave: se
puede deshabilitar el soporte para OpenMP, el cdigo puede ser
compilado como una aplicacin serial.
Ambas API son porttiles, pero Pthreads ofrece una gama
mucho mayor de funciones primitivas que proporcionan un
control ms preciso sobre las operaciones de sobre hilos.
Cabe mencionar que una de las ventajas de Pthreads sobre
OpenMP es que el programador tiene un mayor control sobre la
creacin, destruccin y el comportamiento de los hilos, ya que la
gestin de un hilo est en un nivel ms bajo en Pthreads que en
OpenMP.
En cuanto a MPI se puede decir que necesita que su proceso
maestro haga nicamente un trabajo especfico. La razn detrs
de esto es reducir la sobrecarga en paralelo. Por lo tanto, el
proceso maestro puede centrarse slo en la gestin y
distribucin de datos.
A diferencia de MPI en OpenMP y Pthreads, la gestin de
procesos y sincronizacin se realiza en la misma memoria (es
decir memoria compartida) y no slo el hilo principal sino todos
los hilos tambin son responsables de la sincronizacin de
subprocesos.
Algunas ventajas podran ser que con MPI es ms fcil de
entender cmo se distribuye los datos y cuanto tiempo se uso y
que tiene muchas de las herramientas disponibles para ayudar al
programador. Las desventajas es que tiene una codificacin
compleja de leer, escribir y mantener.

6.

RESULTADOS EXPERIMENTALES

En la siguiente tabla se observa el entorno de ejecucin utilizado


para realizar las pruebas.
Procesador
Intel Core i5M430
CPU 2,27 GHz, 3MB
Cache

Memoria
4GB
DDR3

Disco Duro
HDD 500GB
7200 rpm

S.O.
Ubuntu
11.05

Se implementaron tres aplicaciones en lenguaje C, siendo el


cdigo fuente cada una de las siguientes: pthread_mmult.c,

omp_mmult.c y mpi_mmult.c; con sus respectivos ejecutables


pthread_mmult, omp_mmult y mpi_mmult.

Tabla 2.Tiempo de respuesta para OpenMP

Las aplicaciones se encargan de calcular la multiplicacin de


dos matrices cuadradas, la primera utiliza la librera pthread.h, la
segunda omp.h. y la tercera mpi.h para calcular el desempeo de
la multiplicacin utilizando estos tres enfoques.

Tabla 1.Tiempo de respuesta para Pthread


2 hilos

4 hilos

8 hilos

16 hilos

256

146

76

65

64

512

1210

606

580

577

1024

35060

18572

16726

17087

2048

303670

157734

153238

154699

Se puede ver que a medida que aumenta el tamao de la matriz


aumenta el tiempo de respuesta. Con relacin a si la
paralelizacin a porta o no algn beneficio, se podra ver que en
algunos casos se consigue un mejor tiempo, sin embargo como
las pruebas se realizaron en una maquina de un solo procesador
estos resultados no son concisos.

8 hilos

16 hilos

256

140

70

61

32

512

1414

668

559

522

1024

31743

15793

14245

14381

2048

315383

160211

153761

156366

OPENMP
1000000
100000
256

10000

512

1000

1024

100

2048

10
1
2 hilos

4 hilos
8 hilos
Nro. de Hilos

16 hilos

Figura 2. Tiempo de respuesta en milisegundos para


OpenMP.
Observando los resultados obtenidos con OpenMP se puede ver
que son relativamente parecidos a los obtenidos con Pthreads
por lo cual podemos decir que se comporta de manera similar en
cuanto a tiempo de respuesta.
Tabla 3. Tiempo de respuesta para MPI

En la Figura 1 se observa los valores obtenidos en la tabla


anterior para los distintos tamaos de matrices y cantidades de
hilos con Pthreads.

2 hilos

PTHREADS
1000000
Tiempo de respuesta

4 hilos

En la Figura 2 se observa los valores obtenidos en la tabla


anterior para los distintos tamaos de matrices y cantidades de
hilos con OpenMP.

Tiempo de respuesta

Se ejecutaron las aplicaciones tomando como factores la


dimensin de la matriz y la cantidad de hilos a utilizar. Los
niveles para estos factores son para dimensin de matriz:
256x256, 512x512, 1024x1024, 2048x2048. Y para cantidad de
hilos: 2, 4, 8 y 16. Las pruebas se ejecutaron probando cada
nivel de dimensin de matriz con cada nivel de cantidad de hilo.
Es decir, se ejecutaron las aplicaciones para una dimensin de
256x256 con 2 hilos, con 4 hilos, con 8 hilos y con 16 hilos.
Esto sucesivamente por cada nivel del factor dimensin de
matriz. La mtrica utilizada es el tiempo de respuesta. En las
Tabla 1, 2 y 3; se puede ver el resultado de estas pruebas.

2 hilos

4 hilos

8 hilos

16 hilos

256

74

89

107

248

512

5389

5629

3916

6360

1024

102987

118514

127213

136503

2048

100000
256

10000

512

1000

1024

100

2048

En la Figura 3 se observa los valores obtenidos en la tabla


anterior para los distintos tamaos de matrices y cantidades de
hilos con MPI.

10

MPI

1
4 hilos
8 hilos
Nro. de Hilos

16 hilos

Figura 1. Tiempo de respuesta en milisegundos para


Pthreads.
Observando los resultados obtenidos con Pthreads se puede ver
que a medida que se incrementa el tamao de las matrices
tambin aumenta el tiempo de ejecucin, en donde se nota
mayor diferencia es cuando se pasa de una matriz de tamao 512
a una matriz de tamao 1024.

1000000
Tiempo de respuesta

2 hilos

100000
256

10000

512

1000

1024

100

2048

10
1
2 hilos

4 hilos
8 hilos
Nro. de Hilos

16 hilos

Figura 3. Tiempo de respuesta en milisegundos para MPI.

En las siguientes figuras se muestra el tiempo de ejecucin de


las aplicaciones implementadas en Pthreads, OpenMP y MPI
para una misma dimensin de la matriz.

Multiplicacin de matrices de 1024x1024


160000
Tiempo de respuesta

Observando las tablas y los grficos se puede ver que el tiempo


de ejecucin de OpenMP y Pthread son prcticamente iguales
para un mismo tamao de matriz, lo cual tiene sentido debido a
que se realizo el mismo particionamiento y adems OpenMP es
una capa que te abstrae de la necesidad de inicializar, crear,
liberar los hilos, sin embargo esta basado en Pthreads, en cuanto
a MPI podemos ver que los valores de tiempo de ejecucin son
ms grandes que los obtenidos con OpenMP y Pthreads.

100000

Pthread

80000

OpenMP

60000

MPI

40000
20000
2

4
8
Cantidad de Hilos

16

Figura 6. Tiempo de respuesta en milisegundos para la


multiplicacin de una matriz de 1024x1024

300
Tiempo de respuesta

120000

Multiplicacin de matrices de 256x256

250
200

Pthread

150

OpenMP
MPI

100

140000

Para la Figura 6, se puede ver hubo una pequea mejora para las
distintas cantidades de hilos (2, 4, 8 y 16) de OpenMP con
respecto a Pthreads. As tambin se observa que con MPI se
obtiene mayor tiempo de respuesta que los anteriores.
Multiplicacin de matrices de 2048x2048

50
0
4
8
Cantidad de Hilos

350000

16
Tiempo de respuesta

Figura 4. Tiempo de respuesta en milisegundos para la


multiplicacin de una matriz de 256x256
Para la Figura 4, se puede ver hubo una pequea mejora con la
utilizacin de 2 hilos de Pthread a OpenMP y una gran mejora
en MPI, sin embargo para 8 y 16 hubo un aumento grande de
tiempo de respuesta con MPI.

300000
250000

Pthread

200000

OpenMP

150000

MPI

100000
50000
0
2

16

Cantidad de Hilos

Figura 7. Tiempo de respuesta en milisegundos para la


multiplicacin de una matriz de 2048x2048

Multiplicacin de matrices de 512x512

Tiempo de respuesta

7000
6000
5000

Pthread

4000

OpenMP

3000

MPI

2000

Para la Figura 7, se puede ver hubo un pequeo incremento en


el tiempo de ejecucin de OpenMP con respecto a Pthreads para
2 y 4 hilos, sin embargo segn se puede observar para 8 y 16
hilos ambos muestran un tiempo de respuesta casi igual. Ver la
ltima fila de las Tablas 1, 2 y 3.

1000
0
2

4
8
Cantidad de Hilos

16

Figura 5. Tiempo de respuesta en milisegundos para la


multiplicacin de una matriz de 512x512
Para la Figura 5, de dimensin 512x512, se puede ver que hubo
en todos los casos un gran aumento de tiempo de respuesta con
MPI para todas las cantidades de hilos, sin embargo para
Pthreads y OpenMP se obtuvieron rendimientos similares.

7.

CONCLUSIONES

Como se pudo observar, la diferencia en los tiempos obtenidos


por las implementaciones no fue tan significativa, pero en la
mayora de los casos para este problema, Pthreads obtuvo
resultados ligeramente mejores que OpenMP, sin embargo hay
que resaltar que con MPI se obtuvieron resultados de tiempo
muy elevados con respecto a los otros.
Como las dimensiones de matrices aumentan, la diferencia entre
el tiempo de ejecucin tomada para el clculo de matrices con
OpenMP, PThread y MPI aumenta significativamente. Adems
se puede ver que utilizando el mismo particionamiento en
OpenMP y Pthreads, estos tienen exactamente el mismo
comportamiento teniendo as el mismo tiempo de ejecucin.
OpenMP abstrae de las tareas habituales para el tratamiento de
hilos, lo que lo hace ms fcil de desarrollar, pero as tambin se

tiene menos control sobre los hilos. Es decir, si se necesita un


control fino sobre la paralelizacin se utilizara Pthreads y si se
necesita paralelizar lo ms rpido posible, por ejemplo ya se
posee la aplicacin serial, se utilizara OpenMP.

8.

REFERENCIAS

[1] An Introduction to Parallel Computing. Second Edition.


Addison Wesley
[2] http://www.ibm.com/developerworks/linux/library/lposix1/index.html

Si bien trabajar con Pthreads nos brinda mayor control respecto


de cmo asignar las partes de las matrices a cada thread, tambin
nos diculta la tarea de paralelizar, teniendo que escribir mucho
cdigo. Por otro lado OpenMP resuelve de manera simple la
tarea de paralelizar un cdigo, haciendo que el programador
pueda concentrar sus energas en el algoritmo que esta
codicando y no en la creacin y manipulacin de threads.

[3] http://es.wikipedia.org/wiki/Multiplicaci
%C3%B3n_de_matrices
[4] http://es.wikipedia.org/wiki/OpenMP
[5] http://software.intel.com/en-us/articles/threading-modelsfor-high-performance-computing-pthreads-or-openmp/
[6] D. an Mey, Matrix multiplication using mpi.

9.

ANEXO CDIGOS FUENTES

9.1

Implementacin con Pthreads

/*
============================================================================
NOMBRE: pthread_mmult.c
AUTORES
Roxana Luque - Nelson Molinas
DESCRIPCION
Multiplicacion de matrices con Pthreads
Universidad Nacional de Asuncion - Facultad Politecnica
Carrera: Ingenieria Informatica
Materia: Electiva V - Algoritmos Paralelos
Profesor: Christian Von Lucken
Anho: 2015
============================================================================
*/
#include
#include
#include
#include

<pthread.h>
<stdlib.h>
<stdio.h>
<sys/timeb.h>

int hilos[4]={2,4,8,16};
int **A, **B, **C;
int TAM;
struct registro{

//Cantidad de hilos

int uno;
int dos;
};
int **crearMatriz() {
int i;
int *valores, **temp;
valores = (int *) malloc (TAM * TAM * sizeof(int));
temp = (int **) malloc (TAM * sizeof(int*));
for(i=0; i < TAM; i++)
temp[i] = &(valores[i * TAM]);
return temp;
}
void cargar_matriz(int **matriz, int TAM)
{
int i, j, n = 0;
for (i=0; i<TAM; i++)
for (j=0; j<TAM; j++)
matriz[i][j] = (int) rand()%100;
}
void* mmult (void* param)
{
struct registro *m_param=(struct registro *)param;
int desde = (m_param->uno * TAM)/m_param->dos;
int hasta = ((m_param->uno+1) * TAM)/m_param->dos;
int i,j,k;
for (i=desde; i<hasta; i++)
for (j=0; j<TAM; j++) {
C[i][j]=0;
for (k=0; k<TAM; k++)
C[i][j] += A[i][k]*B[k][j];
}
return 0;
}

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


{
pthread_t *thread; // puntero a un grupo de hilos
int i, j;
struct timeb t_ini, t_fin;
if (argc != 2) {
printf("Ejecutar: %s <TAM>,
argv[0]);
exit(1);
}

donde TAM es la dimension de la matriz\n",

// definiendo el tamanho de la matriz


TAM = atoi(argv[1]);
struct registro *datos=(struct registro *)malloc(sizeof(struct registro));
printf("-----------------------------------------\n");
printf("Multiplicacion de matrices de tamanho %d\n",TAM);
printf("-----------------------------------------\n");
for (j=0; j<=3;j++)
{
A = crearMatriz();
B = crearMatriz();
C = crearMatriz();
//Cargando las matrices con valores
cargar_matriz(A, TAM);
cargar_matriz(B, TAM);

(void) ftime(&t_ini);
thread = (pthread_t *) malloc(hilos[j] * sizeof(pthread_t));
for (i=0; i<hilos[j]; i++)
{
datos->uno=i;
datos->dos=hilos[j];
if (pthread_create (&thread[i], NULL, mmult, datos) != 0 )
{
perror("No se puede crear el hilo");
exit(-1);
}
}

// el hilo principal espera por los otros hilos para completar


for (i=0; i<hilos[j]; i++)
{
pthread_join (thread[i], NULL);
}
(void) ftime(&t_fin);
//tiempo de ejecucin
long
t_tot=(t_fin.timezone*60*1000+t_fin.time*1000+t_fin.millitm)(t_ini.timezone*60*1000+t_ini.time*1000+t_ini.millitm);
printf("\n\n");
printf("Tiempo
de
milisegundos.\n",hilos[j], t_tot);
}
printf("\n");
return 0;
}

9.2

respuesta

para

%d

procesos

es:

Implementacin con OpenMP

/*
============================================================================
NOMBRE: omp_mmult.c
AUTORES
Roxana Luque - Nelson Molinas
DESCRIPCION
Multiplicacion de matrices con OpenMP
Universidad Nacional de Asuncion - Facultad Politecnica
Carrera: Ingenieria Informatica
Materia: Electiva V - Algoritmos Paralelos
Profesor: Christian Von Lucken
Anho: 2015
============================================================================
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <omp.h>
int hilos[4]={2,4,8,16};
int **A, **B, **C;

//Cantidad de hilos

%ld

int TAM;
int **crearMatriz() {
int i;
int *valores, **temp;
valores = (int *) malloc (TAM * TAM * sizeof(int));
temp = (int **) malloc (TAM * sizeof(int*));
for(i=0; i < TAM; i++)
temp[i] = &(valores[i * TAM]);
return temp;
}
void cargar_matriz(int **matriz, int TAM)
{
int i, j, n = 0;
for (i=0; i<TAM; i++)
for (j=0; j<TAM; j++)
matriz[i][j] = (int) rand()%100;
}

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


{
int tid, nthreads, i,j,k, l;
double ini, fin;
if (argc != 2) {
printf("Ejecutar: %s <TAM>,
argv[0]);
exit(1);
}

donde TAM es la dimension de la matriz\n",

// definiendo el tamanho de la matriz


TAM = atoi(argv[1]);
printf("-----------------------------------------\n");
printf("Multiplicacion de matrices de tamanho %d\n",TAM);
printf("-----------------------------------------\n");
for (l=0; l<=3;l++)
{

#pragma
omp
parallel
shared(A,B,C,nthreads)
num_threads(hilos[l])
{
tid = omp_get_thread_num();
if (tid == 0) {
nthreads = omp_get_num_threads();
}
A = crearMatriz();
B = crearMatriz();
C = crearMatriz();
//Cargando las matrices con valores
cargar_matriz(A, TAM);
cargar_matriz(B, TAM);

private(i,j,k,tid)

if (tid == 0)
ini = omp_get_wtime();
//Multiplicacion
#pragma omp for schedule(static, TAM/hilos[l])
for (i=0; i<TAM; i++)
for (j=0; j<TAM; j++) {
C[i][j]=0;
for (k=0; k<TAM; k++)
C[i][j] += A[i][k]*B[k][j];
}
if (tid == 0) {
fin = omp_get_wtime();
printf("\n\n");
printf("
Tiempo
de
milisegundos.\n", hilos[l], (fin-ini)*1000);
}
}
}
printf("\n");
return 0;
}

9.3

respuesta

para

%d

hilos:

Implementacin con MPI

/*
============================================================================
NOMBRE: mpi_mmult.c

%f

AUTOR
Roxana Luque - Nelson Molinas
DESCRIPCION
Multiplicacion de matrices con MPI
Universidad Nacional de Asuncion - Facultad Politecnica
Carrera: Ingenieria Informatica
Materia: Electiva V - Algoritmos Paralelos
Profesor: Christian Von Lucken
Anho: 2015
============================================================================
*/
#include
#include
#include
#include
#include
#include

<mpi.h>
<stdio.h>
<math.h>
<time.h>
<unistd.h>
<stdlib.h>

#define TAM 256

/* Tamanho de las matrices */

int A[TAM][TAM], B[TAM][TAM], C[TAM][TAM];


/* Se carga la matriz con valores desde 0 hasta TAM*TAM */
void cargar_matriz(int m[TAM][TAM])
{
static int n=0;
int i, j;
for (i=0; i<TAM; i++)
for (j=0; j<TAM; j++)
m[i][j] = n++;
}
int main(int argc, char *argv[])
{
int proc, nroproc, i, j, k, sum = 0;
double t_ini=0, t_fin=0;
MPI_Status status;
MPI_Init (&argc, &argv);
/* Numero de procesos que pertenecen al comunicador */

MPI_Comm_size(MPI_COMM_WORLD, &nroproc);
/* Se establece el identificador del proceso llamador en el comunicador */
MPI_Comm_rank(MPI_COMM_WORLD, &proc);
/* El proceso maestro carga las matrices A y B */
if (proc==0) {
printf("-----------------------------------------\n");
printf("Multiplicacion de matrices de tamanho %d\n",TAM);
printf("-----------------------------------------\n");
cargar_matriz(A);
cargar_matriz(B);
}
MPI_Barrier(MPI_COMM_WORLD);
if (proc==0) {
t_ini = MPI_Wtime();
}
/* MPI_Scatter envia partes diferentes de A del proceso fuente, a cada proceso
incluyendose el mismo */
MPI_Scatter (A, TAM*TAM/nroproc, MPI_INT, A, TAM*TAM/nroproc, MPI_INT, 0,
MPI_COMM_WORLD);
/* MPI_Bcast envia B del proceso maestro a todos los procesos */
MPI_Bcast (B, TAM*TAM, MPI_INT, 0, MPI_COMM_WORLD);
/* Se realiza el computo local en cada proceso */
for (i = 0;i<nroproc; i++)
{
if (proc == i)
{
for
(i
=
proc*(TAM/nroproc);
i
<
(proc*(TAM/nroproc)+
(TAM/nroproc)); i++)
{
for (j = proc*(TAM/nroproc); j < (proc*(TAM/nroproc)+
(TAM/nroproc)); j++)
{
for (k = proc*TAM; k < proc*TAM+TAM; k++)
{
sum = sum + A[i][k] * B[k][j];
}
C[i][j] = sum;
sum = 0;
}

}
}
}
MPI_Gather (C,
MPI_COMM_WORLD);

TAM*TAM/nroproc,

MPI_INT,

C,

TAM*TAM/nroproc,

MPI_INT,

/* El proceso maestro devuelve el tiempo de ejecucion*/


if (proc==0) {
t_fin = MPI_Wtime();
printf ("\n");
printf("Tiempo de respuesta para %d hilos: %f milisegundos.\n",
(t_fin-t_ini)*1000);
printf ("\n");
}
/* Realiza tareas de limpieza para finalizar el entorno de ejecucion */
MPI_Finalize();
return 0;
}

0,

nroproc,

Das könnte Ihnen auch gefallen