Vous êtes sur la page 1sur 14

Extensin Guayana

Facultad de Ingeniera
Escuela de Ingeniera Informtica
Paradigmas de Programacin

INTEGRACIN DE RIEMANN

Profesor:

Elaborado por:

Jess Larez

Nader Abu Fakhr


Jos Cols
Moiss Moussa

Ciudad Guayana, julio de 2014

EL PROBLEMA
Se desea implementar la integracin con sumas sucesivas de Riemann, una forma
de abordar el problema de integracin de funciones acotadas. Para esta problemtica
particular se consideran funciones donde la distancia entre los lmites de acotacin es muy
grande y adems se desea un alto grado de precisin, ambos factores incluyen en el costo
computacional del programa cuyo objetivo es realizar la integracin.

Por otra parte, debido a que la integracin por Riemann consiste en la suma del
rea de cada uno de los rectngulos empleados para la aproximacin, se puede considerar
el clculo del rea del rectngulo como un sub-problema que puede ser realizado en un
hilo distinto. En este sentido, una solucin secuencial ejecutada en un entorno paralelo no
aprovechara los recursos ofrecidos por el sistema. Por esto, en base a la problemtica
planteada, se requiere la exploracin de soluciones paralelas de la integracin de
Riemann.

DISEO DE LA SOLUCIN
Se idearon cuatro soluciones, la primera con programacin secuencial y el resto
con programacin paralela, haciendo uso de las libreras MPI, OpenMP y un hbrido de
ambas.

Solucin secuencial
Los datos necesarios en el programa para poder integrar una funcin en este caso
son: el lmite inferior y el lmite superior sobre el cual se define el rea que se desea
calcular y por ltimo la cantidad de rectngulos que el usuario quiere en la sumatoria de
Riemann para el clculo aproximado de la integral. Mientras mayor sea la cantidad de
rectngulos ms preciso ser el resultado obtenido. Si estos parmetros no son recibidos,
el programa utiliza 0 para el lmite inferior, 10 para el superior y 100 rectngulos para
calcular la integral de la funcin 2x-3x por defecto.

P g i n a 2 | 14

Figura 1. Anlisis numrico con la integracin de Riemann.

Solucin con MPI


En MPI se indica el nmero de procesos en los cuales se quiere ejecutar el
programa y estos posteriormente son distribuidos entre los nodos del clster.

Para resolver la integracin, dentro de los lmites de acotacin, la funcin es


dividida en distintos trozos. Cada uno de estos trozos se corresponde con un rectngulo,
la tarea de cada proceso es calcular el rea del rectngulo. El resultado de cada clculo es
sumado con los dems y enviado a un proceso maestro, dnde es almacenado (Ver Figura
2).

Figura 2. Proceso de recopilacin de sumas parciales con MPI_Reduce.


P g i n a 3 | 14

Suponiendo que se tiene la siguiente integral 0 2 2 3 y se quiere paralelizar


en 5 procesos. El clculo de las reas de cado rectngulo sera de la siguiente forma:

Figura 3. Clculo de la integracin de Riemann paralelizado con MPI.

Es importante mencionar que debido a la forma en la cual es dividida la


integracin de la funcin, se obtendr mejor precisin en el clculo de la integral mientras
ms procesos se empleen.

Solucin con OpenMP


La solucin de la integracin en OpenMP es anloga a la solucin en MPI, la
principal diferencia es que en OpenMP se manejan hilos en vez de procesos. Esto tiene
varias ventajas, la principal de estas es el hecho de que los hilos comparten memoria por
lo que los resultados de las sumas parciales no deben ser enviados a travs de una red de
computadores como sucede con MPI. Es importante mencionar que para paralelizar la
tarea, OpenMP brinda numerosas facilidades, ya que basta con indicar el tipo de
reduccin que se va a aplicar y sobre qu variable, la librera se encarga de distribuir esto
en la cantidad de hilos especificados (Ver Figura 4).
#pragma omp parallel for reduction(+:suma) private(i)
for (i = 0; i < n_rectangulos; ++i) {
double x = limite_inferior + i * dx;
double y = f(x);
suma += y * dx;
}

Figura 4. Porcin de cdigo que paraleliza el clculo de rea de los rectngulos.


P g i n a 4 | 14

La precisin de esta solucin no depende de la cantidad de hilos utilizados, ya que


esta es especificada directamente. Sin embargo, si afecta la sobrecarga de cada hilo,
puesto que mientras mayor sea la precisin mayor ser la cantidad de reas que debe
calcular cada hilo.

Solucin hbrida (MPI + OpenMP)


Para resolver la integracin, dentro de los lmites de acotacin, la funcin es
dividida en distintos trozos. Cada uno de estos trozos se corresponde con un rectngulo,
la tarea de cada proceso es calcular el rea del rectngulo. Adems, cada proceso es divido
en varios hilos, por lo tanto, cada hilo realiza el clculo del rea de un rectngulo an ms
pequeo que el definido inicialmente en el proceso. De igual forma que en la
implementacin con MPI, el resultado de cada clculo es sumado con los dems y enviado
a un proceso maestro, dnde es almacenado, como se muestra en la Figura 2.
5

Suponiendo que se tiene la siguiente integral 0 2 2 3 y se quiere paralelizar


en 5 procesos y su vez cada proceso en 2 hilos. El clculo de las reas de cado rectngulo
sera de la siguiente forma:

Figura 5. Clculo de la integracin de Riemann paralelizado con MPI y OpenMP.

P g i n a 5 | 14

PRUEBAS Y RESULTADOS

Secuencial

100000000

Figura 6. Tiempo de ejecucin del clculo de la integral 0

2 2 3 con

1000000000 rectngulos. 44.7 segundos.

MPI

Figura 7. Tiempo de ejecucin de la misma integral del programa secuencial con 22


procesos. 5.16 s.
P g i n a 6 | 14

OpenMP

Figura 8. Tiempo de ejecucin de la misma integral del programa secuencial con 2


hilos. 22.14 s.

Hbrido (MPI + OpenMP)

Figura 9. Tiempo de ejecucin de la misma integral del programa secuencial con 2


procesos y 2 hilos. 5.80 s.
P g i n a 7 | 14

Figura 10. Tiempo de ejecucin de la misma integral del programa secuencial con 20
procesos y 10 hilos. 3.29 s.

Comparacin de resultados
Hibrido 20 procesos 10 hilos
Hibrido 2 procesos 2 hilos
OpenMP 2 Hilos
MPI 22 procesos
Secuencial
0

10

20

30

40

50

Figura 11. Comparacin de tiempos de ejecucin.

P g i n a 8 | 14

IMPLEMENTACIN

Implementacin secuencial
/**
* UCAB Guayana.
* Escuela de Ingeniera Informtica.
* Paradigmas de programacin.
* Nader Abu Fakhr, Jos Cols, Moiss Moussa.
* Integracin con el mtodo de Riemann con ejecucin serializada".
**/
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#define A 0.0
#define B 10.0
#define N 100
// Compilacin: gcc integrar.c -lm -o integrar
void imprimir_ayuda() {
printf("\nEste programa usa el mtodo de Riemann para realizar una
aproximacin a la integral definida (Por defecto 2x-3x).\n\n");
printf("Para llamar al programa: ./integrar <Lmite inferior> <Lmite
superior> <Cantidad de rectngulos>\n\n");
printf(" Lmite inferior: Double, es el lmite inferior de la
integral.\n");
printf(" Lmite superior: Double, es el lmite superior de la
integral.\n");
printf(" Cantidad de rectngulos: Int, mientras mayor sea esta menor ser
el error.\n");
}
double f(double x) {
return (2.0 * x * x) - (3.0 * x);
}
int main(int argc, char *argv[]){
if (argc > 1 && argv[1][0] == '?') {
imprimir_ayuda();
return 0;
}
if(argc > 4){
printf("\nParametros: <Lmite inferior> <Lmite superior> <Cantidad de
rectngulos>\n");
printf("\nLos valores por defecto son:\n\tLmite inferior = %.2f\n\tLmite
superior = %.2f\n\tCantidad de rectngulos = %d\n", A, B, N);
exit(1);
}
const double limite_inferior = argc > 1 ? atof(argv[1]) : A;
const double limite_superior = argc > 2 ? atof(argv[2]) : B;
const int n_rectangulos = argc > 3 ? atoi(argv[3]) : N;
double dx, suma = 0.0;
int i;

P g i n a 9 | 14

dx = (limite_superior - limite_inferior) / n_rectangulos;


for(i = 0; i < n_rectangulos; ++i) {
double x = limite_inferior + i * dx;
double y = f(x);
suma += y * dx;
}
printf("\nIntegral de 2x-3x desde %.2f hasta %.2f es %.3f\n\n",
limite_inferior, limite_superior, suma);
return 0;
}

Implementacin con MPI


/**
* UCAB Guayana.
* Escuela de Ingeniera Informtica.
* Paradigmas de programacin.
* Nader Abu Fakhr, Jos Cols, Moiss Moussa.
* Integracin con el mtodo de Riemann, paralelizado con MPI en varios
nodos.
**/
#include <mpi.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#define N_RECTANGULOS 100
// Compilacin: mpicc integrar_mpi.c -lm -o integrar_mpi
// Ejecucin: mpirun -np 22 -machinefile ./machinefile -nolocal
./integrar_mpi
void imprimir_ayuda() {
printf("\nEste programa usa el mtodo de Riemann para realizar una
aproximacin a la integral definida (Por defecto 2x-3x).\n\n");
printf("Para llamar al programa: mpirun -np 22 -machinefile ./machinefile
-nolocal ./integrar_mpi <Lmite inferior> <Lmite superior> <Cantidad de
rectngulos>\n\n");
printf(" Lmite inferior: Double, es el lmite inferior de la
integral.\n");
printf(" Lmite superior: Double, es el lmite superior de la
integral.\n");
printf(" Cantidad de rectngulos: Int, mientras mayor sea esta menor
ser el error.\n");
}
float f(float x) {
return (2.0 * x * x) - (3.0 * x);
// return cos(x);
}
float integral(float limite_inferior, float dx, int n_rectangulos) {
int i;
float suma = 0.0;
for (i = 0; i < n_rectangulos; ++i) {

P g i n a 10 | 14

float x = limite_inferior + i * dx;


float y = f(x);
suma += y * dx;
}
return suma;
}
int main (int argc, char *argv[]) {
float limite_inferior, limite_inferior_p, limite_superior, dx,
suma_parcial = 0.0, suma;
int i, id, n_rectangulos, n_procesos;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &id);
MPI_Comm_size(MPI_COMM_WORLD, &n_procesos);
if (argc > 1 && argv[1][0] == '?') {
if (!id) imprimir_ayuda();
return 0;
}
limite_inferior = argc > 1 ? atof(argv[1]) : 0.0;
limite_superior = argc > 2 ? atof(argv[2]) : 10.0;
n_rectangulos = argc > 3 ? atoi(argv[3]) : N_RECTANGULOS;
dx = (limite_superior - limite_inferior) / n_rectangulos;
limite_inferior_p = limite_inferior + id * ((dx * n_rectangulos) /
n_procesos);
suma_parcial = integral(limite_inferior_p, dx, (int) n_rectangulos /
n_procesos);
MPI_Reduce(&suma_parcial, &suma, 1, MPI_FLOAT, MPI_SUM, 0,
MPI_COMM_WORLD);
if (!id) printf("\nIntegral de 2x-3x desde %.2f hasta %.2f es %.3f\n\n",
limite_inferior, limite_superior, suma);
MPI_Finalize();
}

Implementacin con OpenMP


/**
* UCAB Guayana.
* Escuela de Ingeniera Informtica.
* Paradigmas de programacin.
* Nader Abu Fakhr, Jos Cols, Moiss Moussa.
* Integracin con el mtodo de Riemann, paralelizado con OpenMP.
**/
#include <omp.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#define N_RECTANGULOS 100
#define N_HILOS 4
// Compilacin: gcc integrar_openmp.c -lm -fopenmp -o integrar_openmp

P g i n a 11 | 14

void imprimir_ayuda() {
printf("\nEste programa usa el mtodo de Riemann para realizar una
aproximacin a la integral definida (Por defecto 2x-3x).\n\n");
printf("Para llamar al programa: ./integrar_openmp <Lmite inferior>
<Lmite superior> <Cantidad de rectngulos> <Cantidad de hilos>\n\n");
printf(" Lmite inferior: Double, es el lmite inferior de la
integral.\n");
printf(" Lmite superior: Double, es el lmite superior de la
integral.\n");
printf(" Cantidad de rectngulos: Int, mientras mayor sea esta menor
ser el error.\n");
printf(" Cantidad de hilos: Int, cantidad de hilos que sern utilizados
para calcular la integral.\n");
}
double f(double x) {
return (2.0 * x * x) - (3.0 * x);
// return cos(x);
}
int main(int argc, char *argv[]){
double limite_inferior, limite_superior, dx, suma = 0.0;
int i, n_rectangulos, n_hilos;
if (argc > 1 && argv[1][0] == '?') {
imprimir_ayuda();
return 0;
}
limite_inferior = argc > 1 ? atof(argv[1]) : 0.0;
limite_superior = argc > 2 ? atof(argv[2]) : 10.0;
n_rectangulos = argc > 3 ? atoi(argv[3]) : N_RECTANGULOS;
n_hilos = argc > 4 ? atoi(argv[4]) : N_HILOS;
dx = (limite_superior - limite_inferior) / n_rectangulos;
omp_set_num_threads(n_hilos);
#pragma omp parallel for reduction(+:suma) private(i)
for (i = 0; i < n_rectangulos; ++i) {
double x = limite_inferior + i * dx;
double y = f(x);
suma += y * dx;
}
printf("\nIntegral de 2x-3x desde %.2f hasta %.2f es %.3f\n\n",
limite_inferior, limite_superior, suma);
return 0;
}

Implementacin hbrida (MPI + OpenMP)


/**
* UCAB Guayana.
* Escuela de Ingeniera Informtica.
* Paradigmas de programacin.
* Nader Abu Fakhr, Jos Cols, Moiss Moussa.

P g i n a 12 | 14

* Integracin con el mtodo de Riemann, paralelizado con MPI en varios nodos


y a la vez en varios hilos con OpenMP.
**/
#include <omp.h>
#include <mpi.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#define N_RECTANGULOS 100
#define N_HILOS 4
// Compilacin: mpicc integrar_hibrido.c -lm -fopenmp -o integrar_hibrido
// Ejecucin: mpirun -np 22 -machinefile ./machinefile -nolocal
./integrar_hibrido
void imprimir_ayuda() {
printf("\nEste programa usa el mtodo de Riemann para realizar una
aproximacin a la integral definida (Por defecto 2x-3x).\n\n");
printf("Para llamar al programa: mpirun -np 22 -machinefile ./machinefile
-nolocal ./integrar_hibrido <Lmite inferior> <Lmite superior> <Cantidad de
rectngulos> <Cantidad de hilos>\n\n");
printf(" Lmite inferior: Double, es el lmite inferior de la
integral.\n");
printf(" Lmite superior: Double, es el lmite superior de la
integral.\n");
printf(" Cantidad de rectngulos: Int, mientras mayor sea esta menor
ser el error.\n");
printf(" Cantidad de hilos: Int, cantidad de hilos que sern utilizados
para calcular la integral.\n");
}
float f(float x) {
return (2.0 * x * x) - (3.0 * x);
// return cos(x);
}
float integral(float limite_inferior, float dx, int n_rectangulos, int
n_hilos) {
int i;
float suma = 0.0;
omp_set_num_threads(n_hilos);
#pragma omp parallel for reduction(+:suma) private(i)
for (i = 0; i < n_rectangulos; ++i) {
float x = limite_inferior + i * dx;
float y = f(x);
suma += y * dx;
}
return suma;
}
int main (int argc, char *argv[]) {
float limite_inferior, limite_inferior_p, limite_superior, dx,
suma_parcial = 0.0, suma;
int i, id, n_rectangulos, n_procesos, n_hilos;
MPI_Init(&argc, &argv);

P g i n a 13 | 14

MPI_Comm_rank(MPI_COMM_WORLD, &id);
MPI_Comm_size(MPI_COMM_WORLD, &n_procesos);
if (argc > 1 && argv[1][0] == '?') {
if (!id) imprimir_ayuda();
return 0;
}
limite_inferior = argc > 1 ? atof(argv[1]) : 0.0;
limite_superior = argc > 2 ? atof(argv[2]) : 10.0;
n_rectangulos = argc > 3 ? atoi(argv[3]) : N_RECTANGULOS;
n_hilos = argc > 4 ? atoi(argv[4]) : N_HILOS;
dx = (limite_superior - limite_inferior) / n_rectangulos;
limite_inferior_p = limite_inferior + id * ((dx * n_rectangulos) /
n_procesos);
suma_parcial = integral(limite_inferior_p, dx, (int) n_rectangulos /
n_procesos, n_hilos);
MPI_Reduce(&suma_parcial, &suma, 1, MPI_FLOAT, MPI_SUM, 0,
MPI_COMM_WORLD);
if (!id) printf("\nIntegral de 2x-3x desde %.2f hasta %.2f es %.3f\n\n",
limite_inferior, limite_superior, suma);
MPI_Finalize();
}

P g i n a 14 | 14

Vous aimerez peut-être aussi